Skip to main content

boa_engine/object/builtins/
jsweakset.rs

1//! A Rust API wrapper for the `WeakSet` Builtin ECMAScript Object
2use std::ops::Deref;
3
4use boa_gc::{Finalize, Trace};
5
6use crate::{
7    Context, JsResult, JsValue,
8    builtins::weak_set::{NativeWeakSet, WeakSet},
9    error::JsNativeError,
10    object::JsObject,
11    value::TryFromJs,
12};
13
14/// `JsWeakSet` provides a wrapper for Boa's implementation of the ECMAScript `WeakSet` object.
15#[derive(Debug, Clone, Trace, Finalize)]
16pub struct JsWeakSet {
17    inner: JsObject,
18}
19
20impl JsWeakSet {
21    /// Creates a new empty `WeakSet`.
22    ///
23    /// More information:
24    ///  - [MDN documentation][mdn]
25    ///
26    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/WeakSet
27    #[inline]
28    pub fn new(context: &mut Context) -> Self {
29        Self {
30            inner: JsObject::from_proto_and_data_with_shared_shape(
31                context.root_shape(),
32                context.intrinsics().constructors().weak_set().prototype(),
33                NativeWeakSet::new(),
34            )
35            .upcast(),
36        }
37    }
38
39    /// Adds the given object to the `WeakSet`.
40    /// Returns the `JsWeakSet` itself.
41    ///
42    /// More information:
43    ///  - [MDN documentation][mdn]
44    ///
45    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/add
46    #[inline]
47    pub fn add(&self, value: &JsObject, context: &mut Context) -> JsResult<Self> {
48        WeakSet::add(&self.inner.clone().into(), &[value.clone().into()], context)?;
49        Ok(self.clone())
50    }
51
52    /// Removes the given object from the `WeakSet`.
53    /// Returns `true` if the element existed, `false` otherwise.
54    ///
55    /// More information:
56    ///  - [MDN documentation][mdn]
57    ///
58    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/delete
59    #[inline]
60    pub fn delete(&self, value: &JsObject, context: &mut Context) -> JsResult<bool> {
61        WeakSet::delete(&self.inner.clone().into(), &[value.clone().into()], context)
62            .map(|v| v.as_boolean().unwrap_or(false))
63    }
64
65    /// Returns `true` if the given object exists in the `WeakSet`.
66    ///
67    /// More information:
68    ///  - [MDN documentation][mdn]
69    ///
70    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/has
71    #[inline]
72    pub fn has(&self, value: &JsObject, context: &mut Context) -> JsResult<bool> {
73        WeakSet::has(&self.inner.clone().into(), &[value.clone().into()], context)
74            .map(|v| v.as_boolean().unwrap_or(false))
75    }
76
77    /// Creates a `JsWeakSet` from a `JsObject`, or returns the original object as `Err`
78    /// if it is not a `WeakSet`.
79    #[inline]
80    pub fn from_object(object: JsObject) -> Result<Self, JsObject> {
81        if object.downcast_ref::<NativeWeakSet>().is_some() {
82            Ok(Self { inner: object })
83        } else {
84            Err(object)
85        }
86    }
87}
88
89impl From<JsWeakSet> for JsObject {
90    #[inline]
91    fn from(o: JsWeakSet) -> Self {
92        o.inner.clone()
93    }
94}
95
96impl From<JsWeakSet> for JsValue {
97    #[inline]
98    fn from(o: JsWeakSet) -> Self {
99        o.inner.clone().into()
100    }
101}
102
103impl Deref for JsWeakSet {
104    type Target = JsObject;
105    #[inline]
106    fn deref(&self) -> &Self::Target {
107        &self.inner
108    }
109}
110
111impl TryFromJs for JsWeakSet {
112    fn try_from_js(value: &JsValue, _context: &mut Context) -> JsResult<Self> {
113        if let Some(o) = value.as_object()
114            && let Ok(weak_set) = Self::from_object(o.clone())
115        {
116            Ok(weak_set)
117        } else {
118            Err(JsNativeError::typ()
119                .with_message("value is not a WeakSet object")
120                .into())
121        }
122    }
123}