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