|
@@ -1,6 +1,9 @@
|
|
//! Utilities specific to websys
|
|
//! Utilities specific to websys
|
|
|
|
|
|
-use std::str::FromStr;
|
|
|
|
|
|
+use std::{
|
|
|
|
+ future::{IntoFuture, Ready},
|
|
|
|
+ str::FromStr,
|
|
|
|
+};
|
|
|
|
|
|
use dioxus_core::*;
|
|
use dioxus_core::*;
|
|
use serde::de::Error;
|
|
use serde::de::Error;
|
|
@@ -19,24 +22,51 @@ use serde_json::Value;
|
|
///
|
|
///
|
|
/// The closure will panic if the provided script is not valid JavaScript code
|
|
/// The closure will panic if the provided script is not valid JavaScript code
|
|
/// or if it returns an uncaught error.
|
|
/// or if it returns an uncaught error.
|
|
-pub fn use_eval<S: std::string::ToString>(
|
|
|
|
- cx: &ScopeState,
|
|
|
|
-) -> &dyn Fn(S) -> Result<Value, serde_json::Error> {
|
|
|
|
|
|
+pub fn use_eval<S: std::string::ToString>(cx: &ScopeState) -> &dyn Fn(S) -> EvalResult {
|
|
cx.use_hook(|| {
|
|
cx.use_hook(|| {
|
|
|script: S| {
|
|
|script: S| {
|
|
let body = script.to_string();
|
|
let body = script.to_string();
|
|
- if let Ok(value) =
|
|
|
|
- js_sys::Function::new_no_args(&body).call0(&wasm_bindgen::JsValue::NULL)
|
|
|
|
- {
|
|
|
|
- if let Ok(stringified) = js_sys::JSON::stringify(&value) {
|
|
|
|
- let string: String = stringified.into();
|
|
|
|
- Value::from_str(&string)
|
|
|
|
|
|
+ EvalResult {
|
|
|
|
+ value: if let Ok(value) =
|
|
|
|
+ js_sys::Function::new_no_args(&body).call0(&wasm_bindgen::JsValue::NULL)
|
|
|
|
+ {
|
|
|
|
+ if let Ok(stringified) = js_sys::JSON::stringify(&value) {
|
|
|
|
+ if !stringified.is_undefined() && stringified.is_valid_utf16() {
|
|
|
|
+ let string: String = stringified.into();
|
|
|
|
+ Value::from_str(&string)
|
|
|
|
+ } else {
|
|
|
|
+ Err(serde_json::Error::custom("Failed to stringify result"))
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ Err(serde_json::Error::custom("Failed to stringify result"))
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
- Err(serde_json::Error::custom("Failed to stringify result"))
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- Err(serde_json::Error::custom("Failed to execute script"))
|
|
|
|
|
|
+ Err(serde_json::Error::custom("Failed to execute script"))
|
|
|
|
+ },
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/// A wrapper around the result of a JavaScript evaluation.
|
|
|
|
+/// This implements IntoFuture to be compatible with the desktop renderer's EvalResult.
|
|
|
|
+pub struct EvalResult {
|
|
|
|
+ value: Result<Value, serde_json::Error>,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl EvalResult {
|
|
|
|
+ /// Get the result of the Javascript execution.
|
|
|
|
+ pub fn get(self) -> Result<Value, serde_json::Error> {
|
|
|
|
+ self.value
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl IntoFuture for EvalResult {
|
|
|
|
+ type Output = Result<Value, serde_json::Error>;
|
|
|
|
+
|
|
|
|
+ type IntoFuture = Ready<Result<Value, serde_json::Error>>;
|
|
|
|
+
|
|
|
|
+ fn into_future(self) -> Self::IntoFuture {
|
|
|
|
+ std::future::ready(self.value)
|
|
|
|
+ }
|
|
|
|
+}
|