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<$generic:ident>) => {
7        impl<$generic> $name<$generic>
8        where
9            Self: ::wasm_bindgen::JsCast,
10        {
11            /// Create a new instance.
12            pub fn new() -> Self {
13                ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new())
14            }
15        }
16
17        impl<$generic> Default for $name<$generic>
18        where
19            Self: ::wasm_bindgen::JsCast,
20        {
21            fn default() -> Self {
22                Self::new()
23            }
24        }
25    };
26
27    ($name:ident) => {
28        impl $name {
29            /// Create a new instance.
30            pub fn new() -> Self {
31                ::js_sys::Object::new().unchecked_into()
32            }
33        }
34
35        impl Default for $name {
36            fn default() -> Self {
37                Self::new()
38            }
39        }
40    };
41}
42
43#[doc(hidden)]
44#[macro_export]
45macro_rules! _dictionary_erase_type_option_jsvalue {
46    (Option<JsValue>) => {
47        JsValue
48    };
49
50    ($t:ty) => {
51        $t
52    };
53}
54
55#[doc(hidden)]
56#[macro_export]
57macro_rules! _dictionary_type_non_wasm_bindgen_accessors {
58    ($attr:ident, JsValue, $js_name:ident) => {
59        ::pastey::paste! {
60            #[doc = "Set `" $js_name "` field to the given value."]
61            pub fn [<set_ $attr>](&self, val: JsValue) {
62                self.[<set_option_ $attr>](val)
63            }
64
65            #[doc = "Unset `" $js_name "` field."]
66            pub fn [<unset_ $attr>](&self) {
67                self.[<set_option_ $attr>](JsValue::NULL)
68            }
69        }
70    };
71
72    ($attr:ident, $value_type:ty, $js_name:ident) => {
73        ::pastey::paste! {
74            #[doc = "Set `" $js_name "` field to the given value."]
75            pub fn [<set_ $attr>](&self, val: $value_type) {
76                self.[<set_option_ $attr>](Some(val))
77            }
78
79            #[doc = "Unset `" $js_name "` field."]
80            pub fn [<unset_ $attr>](&self) {
81                self.[<set_option_ $attr>](None)
82            }
83        }
84    };
85}
86
87/// Define a dictionary type.
88#[macro_export]
89macro_rules! dictionary_type {
90    (
91        $( #[$attrs:meta] )*
92        pub type $name:ident<$generic:ident = $default:ty> {
93            $($attr:ident: $value_type:ty => $js_name:ident)*
94        }
95    ) => {
96        ::pastey::paste! {
97            #[wasm_bindgen]
98            extern "C" {
99                #[doc = "[`" $name "`] dictionary type."]
100                $(#[$attrs])*
101                #[wasm_bindgen(extends = ::js_sys::Object, js_name = Object)]
102                #[derive(Debug, Clone, PartialEq, Eq)]
103                pub type $name<$generic = $default>;
104
105                $(
106                    #[doc = "Get `" $js_name "` field value, if set."]
107                    #[wasm_bindgen(method, getter = $js_name)]
108                    pub fn [<get_ $attr>]<$generic>(this: &$name<$generic>) -> Option<$value_type>;
109
110                    #[doc = "Set `" $js_name "` field to the given value or unset it."]
111                    #[wasm_bindgen(method, setter = $js_name)]
112                    pub fn [<set_option_ $attr>]<$generic>(this: &$name<$generic>, val: Option<$value_type>);
113                )*
114            }
115
116            impl<$generic> $name<$generic>
117            where
118                $generic: ::wasm_bindgen::ErasableGeneric<Repr = ::wasm_bindgen::JsValue>,
119            {
120                $(
121                    $crate::_dictionary_type_non_wasm_bindgen_accessors!($attr, $value_type, $js_name);
122                )*
123            }
124        }
125
126        $crate::dictionary_constructor!($name<$generic>);
127    };
128
129    (
130        $( #[$attrs:meta] )*
131        pub type $name:ident {
132            $($attr:ident: $value_type:ty => $js_name:ident)*
133        }
134    ) => {
135        ::pastey::paste! {
136            #[wasm_bindgen]
137            extern "C" {
138                #[doc = "[`" $name "`] dictionary type."]
139                $(#[$attrs])*
140                #[wasm_bindgen(extends = ::js_sys::Object, js_name = Object)]
141                #[derive(Debug, Clone, PartialEq, Eq)]
142                pub type $name;
143
144                $(
145                    #[doc = "Get `" $js_name "` field value, if set."]
146                    #[wasm_bindgen(method, getter = $js_name)]
147                    pub fn [<get_ $attr>](this: &$name) -> $crate::_dictionary_erase_type_option_jsvalue!(Option<$value_type>);
148
149                    #[doc = "Set `" $js_name "` field to the given value or unset it."]
150                    #[wasm_bindgen(method, setter = $js_name)]
151                    pub fn [<set_option_ $attr>](this: &$name, val: $crate::_dictionary_erase_type_option_jsvalue!(Option<$value_type>));
152                )*
153            }
154
155            impl $name {
156                $(
157                    $crate::_dictionary_type_non_wasm_bindgen_accessors!($attr, $value_type, $js_name);
158                )*
159            }
160        }
161
162        $crate::dictionary_constructor!($name);
163    };
164}
165
166/// Define a set_option_... accessors.
167#[macro_export]
168macro_rules! set_option_accessors {
169    (
170        $( #[$attrs:meta] )*
171        $attr:ident: $value_type:ty
172    ) => {
173        ::pastey::paste! {
174            /// Set field to the given value.
175            $( #[$attrs] )*
176            pub fn [<set_ $attr>](&self, val: $value_type) {
177                self.[<set_option_ $attr>](Some(val))
178            }
179
180            /// Unset field.
181            $( #[$attrs] )*
182            pub fn [<unset_ $attr>](&self) {
183                self.[<set_option_ $attr>](None)
184            }
185        }
186    };
187}
188
189/// Define a set_option_... accessors for a fallible assignment.
190#[macro_export]
191macro_rules! set_option_accessors_fallible {
192    (
193        $( #[$attrs:meta] )*
194        $attr:ident: $value_type:ty => $error_type:ty
195    ) => {
196        ::pastey::paste! {
197            /// Set field to the given value.
198            $( #[$attrs] )*
199            pub fn [<set_ $attr>](&self, val: $value_type) -> Result<(), $error_type> {
200                self.[<set_option_ $attr>](Some(val))
201            }
202
203            /// Unset field.
204            $( #[$attrs] )*
205            pub fn [<unset_ $attr>](&self) -> Result<(), $error_type> {
206                self.[<set_option_ $attr>](None)
207            }
208        }
209    };
210}