napi/bindgen_runtime/js_values/
set.rs

1use std::collections::{BTreeSet, HashSet};
2use std::hash::{BuildHasher, Hash};
3
4#[cfg(feature = "object_indexmap")]
5use indexmap::IndexSet;
6
7use crate::bindgen_prelude::*;
8
9impl<V, S> TypeName for HashSet<V, S> {
10  fn type_name() -> &'static str {
11    "HashSet"
12  }
13
14  fn value_type() -> ValueType {
15    ValueType::Object
16  }
17}
18
19impl<V: FromNapiValue, S> ValidateNapiValue for HashSet<V, S> {}
20
21impl<V, S> ToNapiValue for HashSet<V, S>
22where
23  V: ToNapiValue,
24{
25  unsafe fn to_napi_value(raw_env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
26    let env = Env::from(raw_env);
27    let obj = env.get_global()?;
28    let set_class = obj.get_named_property_unchecked::<Function<'_, Array, ()>>("Set")?;
29    let set = set_class.new_instance(Array::from_vec(&env, val.into_iter().collect())?)?;
30
31    Ok(set.0.value)
32  }
33}
34
35impl<V, S> FromNapiValue for HashSet<V, S>
36where
37  V: FromNapiValue + PartialEq + Eq + Hash,
38  S: Default + BuildHasher,
39{
40  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
41    let obj = Object::from_raw(env, napi_val);
42    let mut set = HashSet::default();
43    let iter_creator: Function<'_, (), Object> = obj.get_named_property("values")?;
44    let iter = iter_creator.apply(obj, ())?;
45    let next: Function<'_, (), Object> = iter.get_named_property("next")?;
46    while {
47      let o: Object = next.apply(iter, ())?;
48      let done: bool = o.get_named_property("done")?;
49      if !done {
50        let v = o.get_named_property_unchecked::<V>("value")?;
51        set.insert(v);
52      }
53      !done
54    } {}
55    Ok(set)
56  }
57}
58
59impl<V> TypeName for BTreeSet<V> {
60  fn type_name() -> &'static str {
61    "BTreeSet"
62  }
63
64  fn value_type() -> ValueType {
65    ValueType::Object
66  }
67}
68
69impl<V: FromNapiValue> ValidateNapiValue for BTreeSet<V> {}
70
71impl<V> ToNapiValue for BTreeSet<V>
72where
73  V: ToNapiValue,
74{
75  unsafe fn to_napi_value(raw_env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
76    let env = Env::from(raw_env);
77    let obj = env.get_global()?;
78    let set_class = obj.get_named_property_unchecked::<Function<'_, Array, ()>>("Set")?;
79    let set = set_class.new_instance(Array::from_vec(&env, val.into_iter().collect())?)?;
80
81    Ok(set.0.value)
82  }
83}
84
85impl<V> FromNapiValue for BTreeSet<V>
86where
87  V: FromNapiValue + Ord,
88{
89  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
90    let obj = unsafe { Object::from_napi_value(env, napi_val)? };
91    let mut set = BTreeSet::default();
92    let iter_creator: Function<'_, (), Object> = obj.get_named_property("values")?;
93    let iter = iter_creator.apply(obj, ())?;
94    let next: Function<'_, (), Object> = iter.get_named_property("next")?;
95    while {
96      let o: Object = next.apply(iter, ())?;
97      let done: bool = o.get_named_property("done")?;
98      if !done {
99        let v = o.get_named_property_unchecked::<V>("value")?;
100        set.insert(v);
101      }
102      !done
103    } {}
104    Ok(set)
105  }
106}
107
108#[cfg(feature = "object_indexmap")]
109impl<V, S> TypeName for IndexSet<V, S> {
110  fn type_name() -> &'static str {
111    "IndexSet"
112  }
113
114  fn value_type() -> ValueType {
115    ValueType::Object
116  }
117}
118#[cfg(feature = "object_indexmap")]
119impl<V: FromNapiValue, S> ValidateNapiValue for IndexSet<V, S> {}
120#[cfg(feature = "object_indexmap")]
121impl<V, S> ToNapiValue for IndexSet<V, S>
122where
123  V: ToNapiValue,
124{
125  unsafe fn to_napi_value(raw_env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
126    let env = Env::from(raw_env);
127    let obj = env.get_global()?;
128    let set_class = obj.get_named_property_unchecked::<Function<'_, Array, ()>>("Set")?;
129    let set = set_class.new_instance(Array::from_vec(&env, val.into_iter().collect())?)?;
130
131    Ok(set.0.value)
132  }
133}
134#[cfg(feature = "object_indexmap")]
135impl<V, S> FromNapiValue for IndexSet<V, S>
136where
137  V: FromNapiValue + PartialEq + Eq + Hash,
138  S: Default + BuildHasher,
139{
140  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
141    let obj = Object::from_raw(env, napi_val);
142    let mut set = IndexSet::default();
143    let iter_creator: Function<'_, (), Object> = obj.get_named_property("values")?;
144    let iter = iter_creator.apply(obj, ())?;
145    let next: Function<'_, (), Object> = iter.get_named_property("next")?;
146    while {
147      let o: Object = next.apply(iter, ())?;
148      let done: bool = o.get_named_property("done")?;
149      if !done {
150        let v = o.get_named_property_unchecked::<V>("value")?;
151        set.insert(v);
152      }
153      !done
154    } {}
155    Ok(set)
156  }
157}