floating_ui/utils_/
object_utils.rs

1use crate::error::{Error, Result};
2use js_sys::{Object, Reflect};
3use wasm_bindgen::JsValue;
4
5pub fn get_js_value(object: &Object, key: &str) -> Result<JsValue> {
6    let property_key = JsValue::from_str(key);
7
8    Reflect::get(&object, &property_key).map_err(Error::map_reflect_get(key.to_string()))
9}
10
11pub fn get_option_js_value(object: &Object, key: &str) -> Result<Option<JsValue>> {
12    let property_key = JsValue::from_str(key);
13
14    let value =
15        Reflect::get(&object, &property_key).map_err(Error::map_reflect_get(key.to_string()))?;
16
17    if value.is_undefined() {
18        Ok(None)
19    } else {
20        Ok(Some(value))
21    }
22}
23
24pub fn try_get<T>(object: &Object, key: &str) -> Result<T>
25where
26    T: TryFrom<JsValue, Error = Error>,
27{
28    get_js_value(object, key)?.try_into()
29}
30
31pub fn try_get_option<T>(object: &Object, key: &str) -> Result<Option<T>>
32where
33    T: TryFrom<JsValue, Error = Error>,
34{
35    if let Some(value) = get_option_js_value(object, key)? {
36        Ok(Some(value.try_into()?))
37    } else {
38        Ok(None)
39    }
40}
41
42pub fn get_f64(object: &Object, key: &str) -> Result<f64> {
43    let value = get_js_value(object, key)?;
44
45    value
46        .as_f64()
47        .ok_or(Error::InvalidJsValue(key.to_string(), "f64"))
48}
49
50pub fn get_option_f64(object: &Object, key: &str) -> Result<Option<f64>> {
51    if let Some(value) = get_option_js_value(object, key)? {
52        Ok(Some(
53            value
54                .as_f64()
55                .ok_or(Error::InvalidJsValue(key.to_string(), "f64"))?,
56        ))
57    } else {
58        Ok(None)
59    }
60}
61
62pub fn get_bool(object: &Object, key: &str) -> Result<bool> {
63    let value = get_js_value(object, key)?;
64
65    value
66        .as_bool()
67        .ok_or(Error::InvalidJsValue(key.to_string(), "bool"))
68}
69
70pub fn get_option_bool(object: &Object, key: &str) -> Result<Option<bool>> {
71    if let Some(value) = get_option_js_value(object, key)? {
72        Ok(Some(
73            value
74                .as_bool()
75                .ok_or(Error::InvalidJsValue(key.to_string(), "bool"))?,
76        ))
77    } else {
78        Ok(None)
79    }
80}
81
82pub fn get_string(object: &Object, key: &str) -> Result<String> {
83    let value = get_js_value(object, key)?;
84
85    value
86        .as_string()
87        .ok_or(Error::InvalidJsValue(key.to_string(), "string"))
88}
89
90pub fn set_f64(object: &Object, key: &str, value: f64) -> Result<()> {
91    let property_key = JsValue::from_str(key);
92    let value = JsValue::from_f64(value);
93
94    let res = Reflect::set(&object, &property_key, &value)
95        .map_err(Error::map_reflect_set(key.to_string()))?;
96
97    if !res {
98        Err(Error::ReflectSet(
99            key.to_string(),
100            "Setting was unsuccessful.".to_string(),
101        ))
102    } else {
103        Ok(())
104    }
105}
106
107pub fn set_option_f64(object: &Object, key: &str, value: Option<f64>) -> Result<()> {
108    if let Some(value) = value {
109        set_f64(object, key, value)
110    } else {
111        Ok(())
112    }
113}
114
115pub fn set_bool(object: &Object, key: &str, value: bool) -> Result<()> {
116    let property_key = JsValue::from_str(key);
117    let value = JsValue::from_bool(value);
118
119    let res = Reflect::set(&object, &property_key, &value)
120        .map_err(Error::map_reflect_set(key.to_string()))?;
121
122    if !res {
123        Err(Error::ReflectSet(
124            key.to_string(),
125            "Setting was unsuccessful.".to_string(),
126        ))
127    } else {
128        Ok(())
129    }
130}
131
132pub fn set_option_bool(object: &Object, key: &str, value: Option<bool>) -> Result<()> {
133    if let Some(value) = value {
134        set_bool(object, key, value)
135    } else {
136        Ok(())
137    }
138}
139
140pub fn try_set_js_value(
141    object: &Object,
142    key: &str,
143    value: impl TryInto<JsValue, Error = Error>,
144) -> Result<()> {
145    set_js_value(object, key, &value.try_into()?)
146}
147
148pub fn set_js_value(object: &Object, key: &str, value: &JsValue) -> Result<()> {
149    let property_key = JsValue::from_str(key);
150
151    let res = Reflect::set(&object, &property_key, value)
152        .map_err(Error::map_reflect_set(key.to_string()))?;
153
154    if !res {
155        Err(Error::ReflectSet(
156            key.to_string(),
157            "Setting was unsuccessful.".to_string(),
158        ))
159    } else {
160        Ok(())
161    }
162}
163
164pub fn try_set_option_js_value(
165    object: &Object,
166    key: &str,
167    value: Option<impl TryInto<JsValue, Error = Error>>,
168) -> Result<()> {
169    if let Some(value) = value {
170        set_js_value(object, key, &value.try_into()?)
171    } else {
172        Ok(())
173    }
174}
175
176pub fn set_option_js_value(object: &Object, key: &str, value: Option<JsValue>) -> Result<()> {
177    if let Some(value) = value {
178        set_js_value(object, key, &value)
179    } else {
180        Ok(())
181    }
182}
183
184pub fn set_string(object: &Object, key: &str, value: &str) -> Result<()> {
185    let property_key = JsValue::from_str(key);
186    let value = JsValue::from_str(value);
187
188    let res = Reflect::set(&object, &property_key, &value)
189        .map_err(Error::map_reflect_set(key.to_string()))?;
190
191    if !res {
192        Err(Error::ReflectSet(
193            key.to_string(),
194            "Setting was unsuccessful.".to_string(),
195        ))
196    } else {
197        Ok(())
198    }
199}
200
201pub fn set_option_string(object: &Object, key: &str, value: Option<&str>) -> Result<()> {
202    if let Some(value) = value {
203        set_string(object, key, value)
204    } else {
205        Ok(())
206    }
207}