eval.rs 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. use std::cell::RefCell;
  2. use std::rc::Rc;
  3. use crate::use_window;
  4. use dioxus_core::ScopeState;
  5. use serde::de::Error;
  6. use std::future::Future;
  7. use std::future::IntoFuture;
  8. use std::pin::Pin;
  9. /// A future that resolves to the result of a JavaScript evaluation.
  10. pub struct EvalResult {
  11. pub(crate) reciever: Rc<RefCell<tokio::sync::mpsc::UnboundedReceiver<serde_json::Value>>>,
  12. }
  13. impl IntoFuture for EvalResult {
  14. type Output = Result<serde_json::Value, serde_json::Error>;
  15. type IntoFuture = Pin<Box<dyn Future<Output = Result<serde_json::Value, serde_json::Error>>>>;
  16. fn into_future(self) -> Self::IntoFuture {
  17. Box::pin(async move {
  18. let mut reciever = self.reciever.borrow_mut();
  19. match reciever.recv().await {
  20. Some(result) => Ok(result),
  21. None => Err(serde_json::Error::custom("No result returned")),
  22. }
  23. }) as Pin<Box<dyn Future<Output = Result<serde_json::Value, serde_json::Error>>>>
  24. }
  25. }
  26. /// Get a closure that executes any JavaScript in the WebView context.
  27. pub fn use_eval(cx: &ScopeState) -> &Rc<dyn Fn(String) -> EvalResult> {
  28. let desktop = use_window(cx);
  29. &*cx.use_hook(|| {
  30. let desktop = desktop.clone();
  31. Rc::new(move |script: String| desktop.eval(&script)) as Rc<dyn Fn(String) -> EvalResult>
  32. })
  33. }