ion/object/
set.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 std::ops::{Deref, DerefMut};
8
9use mozjs::jsapi::{
10	IsSetObject, JSObject, NewSetObject, SetAdd, SetClear, SetDelete, SetEntries, SetForEach, SetHas, SetKeys, SetSize,
11};
12
13use crate::conversions::ToValue as _;
14use crate::{Context, Function, Local, Object, Value};
15
16pub struct Set<'s> {
17	set: Local<'s, *mut JSObject>,
18}
19
20impl<'s> Set<'s> {
21	/// Creates a new empty [Set].
22	pub fn new(cx: &'s Context) -> Set<'s> {
23		Set {
24			set: cx.root(unsafe { NewSetObject(cx.as_ptr()) }),
25		}
26	}
27
28	/// Creates a [Set] from an [Object].
29	///
30	/// Returns [None] if the object is not a set.
31	pub fn from(cx: &Context, object: Local<'s, *mut JSObject>) -> Option<Set<'s>> {
32		Set::is_set(cx, &object).then_some(Set { set: object })
33	}
34
35	/// Creates a [Set] from an [Object].
36	///
37	/// ### Safety
38	/// Object must be a set.
39	pub unsafe fn from_unchecked(object: Local<'s, *mut JSObject>) -> Set<'s> {
40		Set { set: object }
41	}
42
43	/// Returns the size of the [Set].
44	pub fn size(&self, cx: &Context) -> u32 {
45		unsafe { SetSize(cx.as_ptr(), self.handle().into()) }
46	}
47
48	/// Checks if the [Set] contains the given key.
49	pub fn has(&self, cx: &Context, key: &Value) -> bool {
50		let mut has = false;
51		unsafe { SetHas(cx.as_ptr(), self.handle().into(), key.handle().into(), &raw mut has) && has }
52	}
53
54	/// Adds the key to the [Set].
55	pub fn add(&self, cx: &Context, key: &Value) -> bool {
56		unsafe { SetAdd(cx.as_ptr(), self.handle().into(), key.handle().into()) }
57	}
58
59	/// Deletes the key from the [Set].
60	pub fn delete(&self, cx: &Context, key: &Value) -> bool {
61		let mut rval = false;
62		unsafe { SetDelete(cx.as_ptr(), self.handle().into(), key.handle().into(), &raw mut rval) && rval }
63	}
64
65	/// Clears the contents of the [Set].
66	pub fn clear(&self, cx: &Context) -> bool {
67		unsafe { SetClear(cx.as_ptr(), self.handle().into()) }
68	}
69
70	/// Returns an Iterator over the keys of the [Set].
71	pub fn keys<'cx>(&self, cx: &'cx Context) -> Object<'cx> {
72		let mut keys = Value::undefined(cx);
73		unsafe {
74			SetKeys(cx.as_ptr(), self.handle().into(), keys.handle_mut().into());
75		}
76		keys.to_object(cx)
77	}
78
79	/// Returns an Iterator over the entries of the [Set].
80	/// The key and value in each entry are the same.
81	pub fn entries<'cx>(&self, cx: &'cx Context) -> Object<'cx> {
82		let mut entries = Value::undefined(cx);
83		unsafe {
84			SetEntries(cx.as_ptr(), self.handle().into(), entries.handle_mut().into());
85		}
86		entries.to_object(cx)
87	}
88
89	/// Runs the given callback for each entry in the [Set].
90	pub fn for_each(&self, cx: &Context, callback: &Function, this: &Object) -> bool {
91		unsafe {
92			SetForEach(
93				cx.as_ptr(),
94				self.handle().into(),
95				callback.as_value(cx).handle().into(),
96				this.as_value(cx).handle().into(),
97			)
98		}
99	}
100
101	/// Checks if the object is a set.
102	pub fn is_set(cx: &Context, object: &Local<*mut JSObject>) -> bool {
103		let mut set = false;
104		unsafe { IsSetObject(cx.as_ptr(), object.handle().into(), &raw mut set) && set }
105	}
106}
107
108impl<'s> Deref for Set<'s> {
109	type Target = Local<'s, *mut JSObject>;
110
111	fn deref(&self) -> &Self::Target {
112		&self.set
113	}
114}
115
116impl DerefMut for Set<'_> {
117	fn deref_mut(&mut self) -> &mut Self::Target {
118		&mut self.set
119	}
120}