ion/spec/
property.rs

1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 */
6
7use mozjs::jsapi::{
8	JSNativeWrapper, JSPropertySpec, JSPropertySpec_Accessor, JSPropertySpec_AccessorsOrValue,
9	JSPropertySpec_AccessorsOrValue_Accessors, JSPropertySpec_Kind, JSPropertySpec_Name, JSPropertySpec_ValueWrapper,
10	JSPropertySpec_ValueWrapper__bindgen_ty_1, JSPropertySpec_ValueWrapper_Type,
11};
12
13use crate::flags::PropertyFlags;
14use crate::symbol::WellKnownSymbolCode;
15
16/// Creates a [property spec](JSPropertySpec) with a name, getter, setter and attributes.
17pub const fn create_property_spec_accessor(
18	name: &'static str, getter: JSNativeWrapper, setter: JSNativeWrapper, attrs: PropertyFlags,
19) -> JSPropertySpec {
20	JSPropertySpec {
21		name: JSPropertySpec_Name { string_: name.as_ptr().cast() },
22		attributes_: attrs.bits() as u8,
23		kind_: JSPropertySpec_Kind::NativeAccessor,
24		u: JSPropertySpec_AccessorsOrValue {
25			accessors: JSPropertySpec_AccessorsOrValue_Accessors {
26				getter: JSPropertySpec_Accessor { native: getter },
27				setter: JSPropertySpec_Accessor { native: setter },
28			},
29		},
30	}
31}
32
33/// Creates a [property spec](JSPropertySpec) with a name, static string and attributes.
34pub const fn create_property_spec_string(
35	name: &'static str, string: &'static str, attrs: PropertyFlags,
36) -> JSPropertySpec {
37	JSPropertySpec {
38		name: JSPropertySpec_Name { string_: name.as_ptr().cast() },
39		attributes_: attrs.bits() as u8,
40		kind_: JSPropertySpec_Kind::Value,
41		u: JSPropertySpec_AccessorsOrValue {
42			value: JSPropertySpec_ValueWrapper {
43				type_: JSPropertySpec_ValueWrapper_Type::String,
44				__bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 { string: string.as_ptr().cast() },
45			},
46		},
47	}
48}
49
50/// Creates a [property spec](JSPropertySpec) with a name, integer and attributes.
51pub const fn create_property_spec_int(name: &'static str, int: i32, attrs: PropertyFlags) -> JSPropertySpec {
52	JSPropertySpec {
53		name: JSPropertySpec_Name { string_: name.as_ptr().cast() },
54		attributes_: attrs.bits() as u8,
55		kind_: JSPropertySpec_Kind::Value,
56		u: JSPropertySpec_AccessorsOrValue {
57			value: JSPropertySpec_ValueWrapper {
58				type_: JSPropertySpec_ValueWrapper_Type::Int32,
59				__bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 { int32: int },
60			},
61		},
62	}
63}
64
65/// Creates a [property spec](JSPropertySpec) with a name, double and attributes.
66pub const fn create_property_spec_double(name: &'static str, double: f64, attrs: PropertyFlags) -> JSPropertySpec {
67	JSPropertySpec {
68		name: JSPropertySpec_Name { string_: name.as_ptr().cast() },
69		attributes_: attrs.bits() as u8,
70		kind_: JSPropertySpec_Kind::Value,
71		u: JSPropertySpec_AccessorsOrValue {
72			value: JSPropertySpec_ValueWrapper {
73				type_: JSPropertySpec_ValueWrapper_Type::Double,
74				__bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 { double_: double },
75			},
76		},
77	}
78}
79
80/// Creates a [property spec](JSPropertySpec) with a symbol, getter, setter and attributes.
81pub const fn create_property_spec_symbol_accessor(
82	symbol: WellKnownSymbolCode, getter: JSNativeWrapper, setter: JSNativeWrapper, attrs: PropertyFlags,
83) -> JSPropertySpec {
84	JSPropertySpec {
85		name: JSPropertySpec_Name { symbol_: symbol as u32 as usize + 1 },
86		attributes_: attrs.bits() as u8,
87		kind_: JSPropertySpec_Kind::NativeAccessor,
88		u: JSPropertySpec_AccessorsOrValue {
89			accessors: JSPropertySpec_AccessorsOrValue_Accessors {
90				getter: JSPropertySpec_Accessor { native: getter },
91				setter: JSPropertySpec_Accessor { native: setter },
92			},
93		},
94	}
95}
96
97/// Creates a [property spec](JSPropertySpec) with a symbol, static string and attributes.
98pub const fn create_property_spec_symbol_string(
99	symbol: WellKnownSymbolCode, string: &'static str, attrs: PropertyFlags,
100) -> JSPropertySpec {
101	JSPropertySpec {
102		name: JSPropertySpec_Name { symbol_: symbol as u32 as usize + 1 },
103		attributes_: attrs.bits() as u8,
104		kind_: JSPropertySpec_Kind::Value,
105		u: JSPropertySpec_AccessorsOrValue {
106			value: JSPropertySpec_ValueWrapper {
107				type_: JSPropertySpec_ValueWrapper_Type::String,
108				__bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 { string: string.as_ptr().cast() },
109			},
110		},
111	}
112}
113
114/// Creates a [property spec](JSPropertySpec) with a symbol, integer and attributes.
115pub const fn create_property_spec_symbol_int(
116	symbol: WellKnownSymbolCode, int: i32, attrs: PropertyFlags,
117) -> JSPropertySpec {
118	JSPropertySpec {
119		name: JSPropertySpec_Name { symbol_: symbol as u32 as usize + 1 },
120		attributes_: attrs.bits() as u8,
121		kind_: JSPropertySpec_Kind::Value,
122		u: JSPropertySpec_AccessorsOrValue {
123			value: JSPropertySpec_ValueWrapper {
124				type_: JSPropertySpec_ValueWrapper_Type::Int32,
125				__bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 { int32: int },
126			},
127		},
128	}
129}
130
131/// Creates a [property spec](JSPropertySpec) with a symbol, double and attributes.
132pub const fn create_property_spec_symbol_double(
133	symbol: WellKnownSymbolCode, double: f64, attrs: PropertyFlags,
134) -> JSPropertySpec {
135	JSPropertySpec {
136		name: JSPropertySpec_Name { symbol_: symbol as u32 as usize + 1 },
137		attributes_: attrs.bits() as u8,
138		kind_: JSPropertySpec_Kind::Value,
139		u: JSPropertySpec_AccessorsOrValue {
140			value: JSPropertySpec_ValueWrapper {
141				type_: JSPropertySpec_ValueWrapper_Type::Double,
142				__bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 { double_: double },
143			},
144		},
145	}
146}
147
148#[cfg(feature = "macros")]
149#[macro_export(local_inner_macros)]
150macro_rules! property_spec_getter {
151	($getter:expr) => {
152		property_spec_getter!($getter, ::std::stringify!($getter))
153	};
154	($getter:expr, $name:expr) => {
155		property_spec_getter!($getter, $name, $crate::flags::PropertyFlags::ENUMERATE)
156	};
157	($getter:expr, $name:expr, $attrs:expr) => {
158		$crate::spec::create_property_spec_accessor(
159			::std::concat!($name, "\0"),
160			::mozjs::jsapi::JSNativeWrapper {
161				op: Some($getter),
162				info: ::std::ptr::null_mut(),
163			},
164			::mozjs::jsapi::JSNativeWrapper { op: None, info: ::std::ptr::null_mut() },
165			$attrs,
166		)
167	};
168}
169
170#[cfg(feature = "macros")]
171#[macro_export(local_inner_macros)]
172macro_rules! property_spec_setter {
173	($setter:expr) => {
174		property_spec_setter!($setter, ::std::stringify!($setter))
175	};
176	($setter:expr, $name:expr) => {
177		property_spec_setter!($setter, $name, $crate::flags::PropertyFlags::ENUMERATE)
178	};
179	($setter:expr, $name:expr, $attrs:expr) => {
180		$crate::spec::create_property_spec_accessor(
181			::std::concat!($name, "\0"),
182			::mozjs::jsapi::JSNativeWrapper { op: None, info: ::std::ptr::null_mut() },
183			::mozjs::jsapi::JSNativeWrapper {
184				op: Some($setter),
185				info: ::std::ptr::null_mut(),
186			},
187			$attrs,
188		)
189	};
190}
191
192#[cfg(feature = "macros")]
193#[macro_export(local_inner_macros)]
194macro_rules! property_spec_getter_setter {
195	($getter:expr, $setter:expr, $name:expr, $attrs:expr) => {
196		$crate::spec::create_property_spec_accessor(
197			::std::concat!($name, "\0"),
198			::mozjs::jsapi::JSNativeWrapper {
199				op: Some($getter),
200				info: ::std::ptr::null_mut(),
201			},
202			::mozjs::jsapi::JSNativeWrapper {
203				op: Some($setter),
204				info: ::std::ptr::null_mut(),
205			},
206			$attrs,
207		)
208	};
209	($getter:expr, $setter:expr, $name:expr) => {
210		property_spec_getter_setter!($getter, $setter, $name, $crate::flags::PropertyFlags::ENUMERATE)
211	};
212	($getter:expr, $setter:expr) => {
213		property_spec_getter_setter!($getter, $setter, ::std::stringify!($getter))
214	};
215}
216
217#[cfg(feature = "macros")]
218#[macro_export(local_inner_macros)]
219macro_rules! property_spec_symbol_getter {
220	($getter:expr) => {
221		property_spec_symbol_getter!($getter, ::std::stringify!($getter))
222	};
223	($getter:expr, $symbol:expr) => {
224		property_spec_symbol_getter!($getter, $symbol, $crate::flags::PropertyFlags::ENUMERATE)
225	};
226	($getter:expr, $symbol:expr, $attrs:expr) => {
227		$crate::spec::create_property_spec_symbol_accessor(
228			::std::concat!($symbol, "\0"),
229			::mozjs::jsapi::JSNativeWrapper {
230				op: Some($getter),
231				info: ::std::ptr::null_mut(),
232			},
233			::mozjs::jsapi::JSNativeWrapper { op: None, info: ::std::ptr::null_mut() },
234			$attrs,
235		)
236	};
237}
238
239#[cfg(feature = "macros")]
240#[macro_export(local_inner_macros)]
241macro_rules! property_spec_symbol_setter {
242	($setter:expr) => {
243		property_spec_symbol_setter!($setter, ::std::stringify!($setter))
244	};
245	($setter:expr, $symbol:expr) => {
246		property_spec_symbol_setter!($setter, $symbol, $crate::flags::PropertyFlags::ENUMERATE)
247	};
248	($setter:expr, $symbol:expr, $attrs:expr) => {
249		$crate::spec::create_property_spec_symbol_accessor(
250			::std::concat!($symbol, "\0"),
251			::mozjs::jsapi::JSNativeWrapper { op: None, info: ::std::ptr::null_mut() },
252			::mozjs::jsapi::JSNativeWrapper {
253				op: Some($setter),
254				info: ::std::ptr::null_mut(),
255			},
256			$attrs,
257		)
258	};
259}
260
261#[cfg(feature = "macros")]
262#[macro_export(local_inner_macros)]
263macro_rules! property_spec_symbol_getter_setter {
264	($getter:expr, $setter:expr, $symbol:expr, $attrs:expr) => {
265		$crate::spec::create_property_spec_symbol_accessor(
266			::std::concat!($symbol, "\0"),
267			::mozjs::jsapi::JSNativeWrapper {
268				op: Some($getter),
269				info: ::std::ptr::null_mut(),
270			},
271			::mozjs::jsapi::JSNativeWrapper {
272				op: Some($setter),
273				info: ::std::ptr::null_mut(),
274			},
275			$attrs,
276		)
277	};
278	($getter:expr, $setter:expr, $symbol:expr) => {
279		property_spec_symbol_getter_setter!($getter, $setter, $symbol, $crate::flags::PropertyFlags::ENUMERATE)
280	};
281	($getter:expr, $setter:expr) => {
282		property_spec_symbol_getter_setter!($getter, $setter, ::std::stringify!($getter))
283	};
284}