tauri_wasm/
serde.rs

1use {
2    crate::{
3        error::Error,
4        invoke::{Options, ToArgs},
5    },
6    serde::{Serialize, Serializer as _, ser},
7    serde_wasm_bindgen::Serializer,
8    std::collections::HashMap,
9    wasm_bindgen::JsValue,
10};
11
12/// Arbitrary serializable data for
13/// [`with_args`](crate::invoke::Invoke::with_args) function.
14///
15/// Returns an [error](Error) if serialization fails.
16///
17/// # Example
18///
19#[cfg_attr(feature = "serde", doc = "```")]
20#[cfg_attr(not(feature = "serde"), doc = "```ignore")]
21/// # async fn e() -> Result<(), tauri_wasm::Error> {
22/// use {gloo::console, std::collections::HashMap};
23///
24/// let data = HashMap::from([
25///     ("token", 4),
26///     ("secret", 7),
27/// ]);
28///
29/// let args = tauri_wasm::args(&data)?;
30/// let message = tauri_wasm::invoke("pass").with_args(args).await?;
31/// console::log!("passed to backend", message);
32/// # Ok(())
33/// # }
34/// ```
35#[inline]
36pub fn args<T>(args: &T) -> Result<impl ToArgs, Error>
37where
38    T: Serialize + ?Sized,
39{
40    struct Data(JsValue);
41
42    impl ToArgs for Data {
43        type Js = JsValue;
44
45        fn to_args(self) -> Self::Js {
46            self.0
47        }
48    }
49
50    let data = serde_wasm_bindgen::to_value(args).map_err(|e| Error(JsValue::from(e)))?;
51    Ok(Data(data))
52}
53
54impl Options {
55    #[inline]
56    pub fn from_map<K, V>(map: &HashMap<K, V>) -> Result<Self, Error>
57    where
58        K: AsRef<str>,
59        V: AsRef<str>,
60    {
61        use ser::SerializeMap;
62
63        let error = |e| Error(JsValue::from(e));
64
65        let ser = Serializer::new();
66        let mut s = ser.serialize_map(Some(map.len())).map_err(error)?;
67
68        for (key, val) in map {
69            s.serialize_entry(key.as_ref(), val.as_ref())
70                .map_err(error)?;
71        }
72
73        let headers = s.end().map_err(error)?;
74        Ok(Self { headers })
75    }
76
77    #[inline]
78    pub fn from_record<'val, I>(fields: I) -> Result<Self, Error>
79    where
80        I: IntoIterator<IntoIter: ExactSizeIterator, Item = (&'static str, &'val str)>,
81    {
82        use ser::SerializeStruct;
83
84        let fields = fields.into_iter();
85        let error = |e| Error(JsValue::from(e));
86
87        let ser = Serializer::new();
88        let mut s = ser
89            .serialize_struct("Record", fields.len())
90            .map_err(error)?;
91
92        for (key, val) in fields {
93            s.serialize_field(key, val).map_err(error)?;
94        }
95
96        let headers = s.end().map_err(error)?;
97        Ok(Self { headers })
98    }
99}