wasm_bindgen_derive/
helpers.rs1use alloc::format;
2use alloc::string::String;
3use alloc::vec::Vec;
4
5use wasm_bindgen::{JsCast, JsValue};
6
7pub fn into_js_option<T, U>(val: Option<U>) -> T
21where
22 JsValue: From<U>,
23 T: JsCast,
24{
25 let js_val = match val {
26 None => JsValue::UNDEFINED,
27 Some(val) => val.into(),
28 };
29 js_val.unchecked_into::<T>()
30}
31
32pub fn try_from_js_option<T>(val: impl Into<JsValue>) -> Result<Option<T>, String>
35where
36 for<'a> T: TryFrom<&'a JsValue>,
37 for<'a> <T as TryFrom<&'a JsValue>>::Error: core::fmt::Display,
38{
39 let js_val = val.into();
40 if js_val.is_undefined() {
41 return Ok(None);
42 }
43 T::try_from(&js_val)
44 .map(Some)
45 .map_err(|err| format!("{}", err))
46}
47
48pub fn into_js_array<T, U>(value: impl IntoIterator<Item = U>) -> T
60where
61 JsValue: From<U>,
62 T: JsCast,
63{
64 value
65 .into_iter()
66 .map(JsValue::from)
67 .collect::<js_sys::Array>()
68 .unchecked_into::<T>()
69}
70
71pub fn try_from_js_array<T>(val: impl Into<JsValue>) -> Result<Vec<T>, String>
73where
74 for<'a> T: TryFrom<&'a JsValue>,
75 for<'a> <T as TryFrom<&'a JsValue>>::Error: core::fmt::Display,
76{
77 let js_val = val.into();
78 let array: &js_sys::Array = js_val.dyn_ref().ok_or("The argument must be an array")?;
79 let length: usize = array
80 .length()
81 .try_into()
82 .map_err(|err| format!("{}", err))?;
83 let mut typed_array = Vec::<T>::with_capacity(length);
84 for (idx, js) in array.iter().enumerate() {
85 let typed_elem =
86 T::try_from(&js).map_err(|err| format!("Failed to cast item {}: {}", idx, err))?;
87 typed_array.push(typed_elem);
88 }
89 Ok(typed_array)
90}