boa/value/
conversions.rs

1use super::*;
2use std::convert::TryFrom;
3
4impl From<&JsValue> for JsValue {
5    #[inline]
6    fn from(value: &JsValue) -> Self {
7        value.clone()
8    }
9}
10
11impl<T> From<T> for JsValue
12where
13    T: Into<JsString>,
14{
15    #[inline]
16    fn from(value: T) -> Self {
17        let _timer = BoaProfiler::global().start_event("From<String>", "value");
18
19        Self::String(value.into())
20    }
21}
22
23impl From<char> for JsValue {
24    #[inline]
25    fn from(value: char) -> Self {
26        JsValue::new(value.to_string())
27    }
28}
29
30impl From<JsSymbol> for JsValue {
31    #[inline]
32    fn from(value: JsSymbol) -> Self {
33        JsValue::Symbol(value)
34    }
35}
36
37#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
38pub struct TryFromCharError;
39
40impl Display for TryFromCharError {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        write!(f, "Could not convert value to a char type")
43    }
44}
45
46impl From<f64> for JsValue {
47    #[allow(clippy::float_cmp)]
48    #[inline]
49    fn from(value: f64) -> Self {
50        // if value as i32 as f64 == value {
51        //     JsValue::Integer(value as i32)
52        // } else {
53        JsValue::Rational(value)
54        // }
55    }
56}
57
58impl From<u32> for JsValue {
59    #[inline]
60    fn from(value: u32) -> JsValue {
61        if let Ok(integer) = i32::try_from(value) {
62            JsValue::Integer(integer)
63        } else {
64            JsValue::Rational(value.into())
65        }
66    }
67}
68
69impl From<i32> for JsValue {
70    #[inline]
71    fn from(value: i32) -> JsValue {
72        JsValue::Integer(value)
73    }
74}
75
76impl From<JsBigInt> for JsValue {
77    #[inline]
78    fn from(value: JsBigInt) -> Self {
79        JsValue::BigInt(value)
80    }
81}
82
83impl From<usize> for JsValue {
84    #[inline]
85    fn from(value: usize) -> JsValue {
86        if let Ok(value) = i32::try_from(value) {
87            JsValue::Integer(value)
88        } else {
89            JsValue::Rational(value as f64)
90        }
91    }
92}
93
94impl From<u64> for JsValue {
95    #[inline]
96    fn from(value: u64) -> JsValue {
97        if let Ok(value) = i32::try_from(value) {
98            JsValue::Integer(value)
99        } else {
100            JsValue::Rational(value as f64)
101        }
102    }
103}
104
105impl From<i64> for JsValue {
106    #[inline]
107    fn from(value: i64) -> JsValue {
108        if let Ok(value) = i32::try_from(value) {
109            JsValue::Integer(value)
110        } else {
111            JsValue::Rational(value as f64)
112        }
113    }
114}
115
116impl From<bool> for JsValue {
117    #[inline]
118    fn from(value: bool) -> Self {
119        JsValue::Boolean(value)
120    }
121}
122
123impl<T> From<&[T]> for JsValue
124where
125    T: Clone + Into<JsValue>,
126{
127    fn from(value: &[T]) -> Self {
128        let mut array = Object::default();
129        for (i, item) in value.iter().enumerate() {
130            array.insert(
131                i,
132                PropertyDescriptor::builder()
133                    .value(item.clone())
134                    .writable(true)
135                    .enumerable(true)
136                    .configurable(true),
137            );
138        }
139        Self::from(array)
140    }
141}
142
143impl<T> From<Vec<T>> for JsValue
144where
145    T: Into<JsValue>,
146{
147    fn from(value: Vec<T>) -> Self {
148        let mut array = Object::default();
149        for (i, item) in value.into_iter().enumerate() {
150            array.insert(
151                i,
152                PropertyDescriptor::builder()
153                    .value(item)
154                    .writable(true)
155                    .enumerable(true)
156                    .configurable(true),
157            );
158        }
159        JsValue::new(array)
160    }
161}
162
163impl From<Object> for JsValue {
164    #[inline]
165    fn from(object: Object) -> Self {
166        let _timer = BoaProfiler::global().start_event("From<Object>", "value");
167        JsValue::Object(JsObject::new(object))
168    }
169}
170
171impl From<JsObject> for JsValue {
172    #[inline]
173    fn from(object: JsObject) -> Self {
174        let _timer = BoaProfiler::global().start_event("From<JsObject>", "value");
175        JsValue::Object(object)
176    }
177}
178
179#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
180pub struct TryFromObjectError;
181
182impl Display for TryFromObjectError {
183    #[inline]
184    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185        write!(f, "Could not convert value to an Object type")
186    }
187}
188
189impl From<()> for JsValue {
190    #[inline]
191    fn from(_: ()) -> Self {
192        JsValue::null()
193    }
194}
195
196impl<T> From<Option<T>> for JsValue
197where
198    T: Into<JsValue>,
199{
200    #[inline]
201    fn from(value: Option<T>) -> Self {
202        match value {
203            Some(value) => value.into(),
204            None => JsValue::null(),
205        }
206    }
207}