Skip to main content

web_wt_sys/
macros.rs

1//! Macros.
2
3/// Define a dictionary constructor.
4#[macro_export]
5macro_rules! dictionary_constructor {
6    ($name:ident) => {
7        impl $name {
8            /// Create a new instance.
9            pub fn new() -> Self {
10                ::js_sys::Object::new().unchecked_into()
11            }
12        }
13
14        impl Default for $name {
15            fn default() -> Self {
16                Self::new()
17            }
18        }
19    };
20}
21
22#[doc(hidden)]
23#[macro_export]
24macro_rules! _dictionary_erase_type_option_jsvalue {
25    (Option<JsValue>) => {
26        JsValue
27    };
28
29    ($t:ty) => {
30        $t
31    };
32}
33
34#[doc(hidden)]
35#[macro_export]
36macro_rules! _dictionary_type_non_wasm_bindgen_accessors {
37    ($attr:ident, JsValue, $js_name:ident) => {
38        ::pastey::paste! {
39            #[doc = "Set `" $js_name "` field to the given value."]
40            pub fn [<set_ $attr>](&self, val: JsValue) {
41                self.[<set_option_ $attr>](val)
42            }
43
44            #[doc = "Unset `" $js_name "` field."]
45            pub fn [<unset_ $attr>](&self) {
46                self.[<set_option_ $attr>](JsValue::NULL)
47            }
48        }
49    };
50
51    ($attr:ident, $value_type:ty, $js_name:ident) => {
52        ::pastey::paste! {
53            #[doc = "Set `" $js_name "` field to the given value."]
54            pub fn [<set_ $attr>](&self, val: $value_type) {
55                self.[<set_option_ $attr>](Some(val))
56            }
57
58            #[doc = "Unset `" $js_name "` field."]
59            pub fn [<unset_ $attr>](&self) {
60                self.[<set_option_ $attr>](None)
61            }
62        }
63    };
64}
65
66/// Define a dictionary type.
67#[macro_export]
68macro_rules! dictionary_type {
69    (
70        $( #[$attrs:meta] )*
71        pub type $name:ident {
72            $($attr:ident: $value_type:ty => $js_name:ident)*
73        }
74    ) => {
75        ::pastey::paste! {
76            #[wasm_bindgen]
77            extern "C" {
78                #[doc = "[`" $name "`] dictionary type."]
79                $(#[$attrs])*
80                #[wasm_bindgen(extends = ::js_sys::Object, js_name = Object)]
81                #[derive(Debug, Clone, PartialEq, Eq)]
82                pub type $name;
83
84                $(
85                    #[doc = "Get `" $js_name "` field value, if set."]
86                    #[wasm_bindgen(method, getter = $js_name)]
87                    pub fn [<get_ $attr>](this: &$name) -> $crate::_dictionary_erase_type_option_jsvalue!(Option<$value_type>);
88
89                    #[doc = "Set `" $js_name "` field to the given value or unset it."]
90                    #[wasm_bindgen(method, setter = $js_name)]
91                    pub fn [<set_option_ $attr>](this: &$name, val: $crate::_dictionary_erase_type_option_jsvalue!(Option<$value_type>));
92                )*
93            }
94
95            impl $name {
96                $(
97                    $crate::_dictionary_type_non_wasm_bindgen_accessors!($attr, $value_type, $js_name);
98                )*
99            }
100        }
101
102        $crate::dictionary_constructor!($name);
103    };
104}
105
106/// Define a set_option_... accessors.
107#[macro_export]
108macro_rules! set_option_accessors {
109    (
110        $( #[$attrs:meta] )*
111        $attr:ident: $value_type:ty
112    ) => {
113        ::pastey::paste! {
114            /// Set field to the given value.
115            $( #[$attrs] )*
116            pub fn [<set_ $attr>](&self, val: $value_type) {
117                self.[<set_option_ $attr>](Some(val))
118            }
119
120            /// Unset field.
121            $( #[$attrs] )*
122            pub fn [<unset_ $attr>](&self) {
123                self.[<set_option_ $attr>](None)
124            }
125        }
126    };
127}
128
129/// Define a set_option_... accessors for a fallible assignment.
130#[macro_export]
131macro_rules! set_option_accessors_fallible {
132    (
133        $( #[$attrs:meta] )*
134        $attr:ident: $value_type:ty => $error_type:ty
135    ) => {
136        ::pastey::paste! {
137            /// Set field to the given value.
138            $( #[$attrs] )*
139            pub fn [<set_ $attr>](&self, val: $value_type) -> Result<(), $error_type> {
140                self.[<set_option_ $attr>](Some(val))
141            }
142
143            /// Unset field.
144            $( #[$attrs] )*
145            pub fn [<unset_ $attr>](&self) -> Result<(), $error_type> {
146                self.[<set_option_ $attr>](None)
147            }
148        }
149    };
150}