tsify_next/
lib.rs

1#![allow(clippy::wrong_self_convention)]
2
3#[cfg(not(any(feature = "json", feature = "js")))]
4compile_error!(
5    "Either the \"json\" or \"js\" feature must be enabled for tsify to function properly"
6);
7
8#[cfg(all(feature = "json", not(feature = "js")))]
9pub use gloo_utils::format::JsValueSerdeExt;
10#[cfg(feature = "js")]
11pub use serde_wasm_bindgen;
12pub use tsify_next_macros::*;
13#[cfg(feature = "wasm-bindgen")]
14use wasm_bindgen::{JsCast, JsValue};
15
16pub struct SerializationConfig {
17    pub missing_as_null: bool,
18    pub hashmap_as_object: bool,
19    pub large_number_types_as_bigints: bool,
20}
21
22/// `Tsify` is a trait that allows you to convert a type to and from JavaScript.
23/// Can be implemented manually if you need to customize the serialization or deserialization.
24pub trait Tsify {
25    #[cfg(feature = "wasm-bindgen")]
26    type JsType: JsCast;
27
28    const DECL: &'static str;
29    const SERIALIZATION_CONFIG: SerializationConfig = SerializationConfig {
30        missing_as_null: false,
31        hashmap_as_object: false,
32        large_number_types_as_bigints: false,
33    };
34
35    #[cfg(all(feature = "json", not(feature = "js")))]
36    #[inline]
37    fn into_js(&self) -> serde_json::Result<Self::JsType>
38    where
39        Self: serde::Serialize,
40    {
41        JsValue::from_serde(self).map(JsCast::unchecked_from_js)
42    }
43
44    #[cfg(all(feature = "json", not(feature = "js")))]
45    #[inline]
46    fn from_js<T: Into<JsValue>>(js: T) -> serde_json::Result<Self>
47    where
48        Self: serde::de::DeserializeOwned,
49    {
50        js.into().into_serde()
51    }
52
53    #[cfg(feature = "js")]
54    #[inline]
55    fn into_js(&self) -> Result<Self::JsType, serde_wasm_bindgen::Error>
56    where
57        Self: serde::Serialize,
58    {
59        let config = <Self as Tsify>::SERIALIZATION_CONFIG;
60        let serializer = serde_wasm_bindgen::Serializer::new()
61            .serialize_missing_as_null(config.missing_as_null)
62            .serialize_maps_as_objects(config.hashmap_as_object)
63            .serialize_large_number_types_as_bigints(config.large_number_types_as_bigints);
64        self.serialize(&serializer).map(JsCast::unchecked_from_js)
65    }
66
67    #[cfg(feature = "js")]
68    #[inline]
69    fn from_js<T: Into<JsValue>>(js: T) -> Result<Self, serde_wasm_bindgen::Error>
70    where
71        Self: serde::de::DeserializeOwned,
72    {
73        serde_wasm_bindgen::from_value(js.into())
74    }
75}