boa_engine/value/conversions/try_from_js/
collections.rs1use std::collections::{BTreeMap, HashMap};
4use std::hash::Hash;
5
6use crate::object::JsMap;
7use crate::value::TryFromJs;
8use crate::{Context, JsNativeError, JsResult, JsValue};
9
10impl<K, V> TryFromJs for BTreeMap<K, V>
11where
12 K: TryFromJs + Ord,
13 V: TryFromJs,
14{
15 fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
16 let Some(object) = value.as_object() else {
17 return Err(JsNativeError::typ()
18 .with_message("cannot convert value to a BTreeMap")
19 .into());
20 };
21
22 if let Ok(js_map) = JsMap::from_object(object.clone()) {
24 let mut map = Self::default();
25 js_map.for_each_native(|key, value| {
26 map.insert(
27 K::try_from_js(&key, context)?,
28 V::try_from_js(&value, context)?,
29 );
30 Ok(())
31 })?;
32 return Ok(map);
33 }
34
35 let keys = object.__own_property_keys__(context)?;
37
38 keys.into_iter()
39 .map(|key| {
40 let js_value = object.get(key.clone(), context)?;
41 let js_key: JsValue = key.into();
42
43 let key = K::try_from_js(&js_key, context)?;
44 let value = V::try_from_js(&js_value, context)?;
45
46 Ok((key, value))
47 })
48 .collect()
49 }
50}
51
52impl<K, V, S> TryFromJs for HashMap<K, V, S>
53where
54 K: TryFromJs + Ord + Hash,
55 V: TryFromJs,
56 S: std::hash::BuildHasher + Default,
57{
58 fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
59 let Some(object) = value.as_object() else {
60 return Err(JsNativeError::typ()
61 .with_message("cannot convert value to a BTreeMap")
62 .into());
63 };
64
65 if let Ok(js_map) = JsMap::from_object(object.clone()) {
67 let mut map = Self::default();
68 js_map.for_each_native(|key, value| {
69 map.insert(
70 K::try_from_js(&key, context)?,
71 V::try_from_js(&value, context)?,
72 );
73 Ok(())
74 })?;
75 return Ok(map);
76 }
77
78 let keys = object.__own_property_keys__(context)?;
80
81 keys.into_iter()
82 .map(|key| {
83 let js_value = object.get(key.clone(), context)?;
84 let js_key: JsValue = key.into();
85
86 let key = K::try_from_js(&js_key, context)?;
87 let value = V::try_from_js(&js_value, context)?;
88
89 Ok((key, value))
90 })
91 .collect()
92 }
93}