air_interpreter_value/value/
from.rs

1/*
2 * Copyright 2024 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * This file is based on serde_json crate by Erick Tryzelaar and David Tolnay
19 * licensed under conditions of MIT License and Apache License, Version 2.0.
20 */
21
22use super::JValue;
23use crate::{JsonString, Map};
24use serde_json::Number;
25use std::borrow::Cow;
26use std::collections::HashMap;
27use std::rc::Rc;
28use std::string::String;
29use std::vec::Vec;
30
31macro_rules! from_integer {
32    ($($ty:ident)*) => {
33        $(
34            impl From<$ty> for JValue {
35                fn from(n: $ty) -> Self {
36                    JValue::Number(n.into())
37                }
38            }
39        )*
40    };
41}
42
43from_integer! {
44    i8 i16 i32 i64 isize
45    u8 u16 u32 u64 usize
46}
47
48impl From<f32> for JValue {
49    /// Convert 32-bit floating point number to `JValue::Number`, or
50    /// `JValue::Null` if infinite or NaN.
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// use air_interpreter_value::JValue;
56    ///
57    /// let f: f32 = 13.37;
58    /// let x: JValue = f.into();
59    /// ```
60    fn from(f: f32) -> Self {
61        Number::from_f64(f as _).map_or(JValue::Null, JValue::Number)
62    }
63}
64
65impl From<f64> for JValue {
66    /// Convert 64-bit floating point number to `JValue::Number`, or
67    /// `JValue::Null` if infinite or NaN.
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// use air_interpreter_value::JValue;
73    ///
74    /// let f: f64 = 13.37;
75    /// let x: JValue = f.into();
76    /// ```
77    fn from(f: f64) -> Self {
78        Number::from_f64(f).map_or(JValue::Null, JValue::Number)
79    }
80}
81
82impl From<bool> for JValue {
83    /// Convert boolean to `JValue::Bool`.
84    ///
85    /// # Examples
86    ///
87    /// ```
88    /// use air_interpreter_value::JValue;
89    ///
90    /// let b = false;
91    /// let x: JValue = b.into();
92    /// ```
93    fn from(f: bool) -> Self {
94        JValue::Bool(f)
95    }
96}
97
98impl From<String> for JValue {
99    /// Convert `String` to `JValue::String`.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use air_interpreter_value::JValue;
105    ///
106    /// let s: String = "lorem".to_string();
107    /// let x: JValue = s.into();
108    /// ```
109    fn from(f: String) -> Self {
110        JValue::String(f.into())
111    }
112}
113
114impl From<JsonString> for JValue {
115    /// Convert `JsonString` to `JValue::String`.
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use air_interpreter_value::JValue;
121    ///
122    /// let s: String = "lorem".to_string();
123    /// let x: JValue = s.into();
124    /// ```
125    fn from(f: JsonString) -> Self {
126        JValue::String(f)
127    }
128}
129
130impl From<&str> for JValue {
131    /// Convert string slice to `JValue::String`.
132    ///
133    /// # Examples
134    ///
135    /// ```
136    /// use air_interpreter_value::JValue;
137    ///
138    /// let s: &str = "lorem";
139    /// let x: JValue = s.into();
140    /// ```
141    fn from(f: &str) -> Self {
142        JValue::String(f.into())
143    }
144}
145
146impl<'a> From<Cow<'a, str>> for JValue {
147    /// Convert copy-on-write string to `JValue::String`.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// use air_interpreter_value::JValue;
153    /// use std::borrow::Cow;
154    ///
155    /// let s: Cow<str> = Cow::Borrowed("lorem");
156    /// let x: JValue = s.into();
157    /// ```
158    ///
159    /// ```
160    /// use air_interpreter_value::JValue;
161    /// use std::borrow::Cow;
162    ///
163    /// let s: Cow<str> = Cow::Owned("lorem".to_string());
164    /// let x: JValue = s.into();
165    /// ```
166    fn from(f: Cow<'a, str>) -> Self {
167        JValue::String(f.into())
168    }
169}
170
171impl From<Number> for JValue {
172    /// Convert `serde_json::Number` to `JValue::Number`.
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// use serde_json::Number;
178    /// use air_interpreter_value::JValue;
179    ///
180    /// let n = Number::from(7);
181    /// let x: JValue = n.into();
182    /// ```
183    fn from(f: Number) -> Self {
184        JValue::Number(f)
185    }
186}
187
188impl From<Map<JsonString, JValue>> for JValue {
189    /// Convert map (with string keys) to `JValue::Object`.
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// use air_interpreter_value::{Map, JValue, JsonString};
195    ///
196    /// let mut m = Map::<JsonString, JValue>::new();
197    /// m.insert("Lorem".into(), "ipsum".into());
198    /// let x: JValue = m.into();
199    /// ```
200    fn from(f: Map<JsonString, JValue>) -> Self {
201        JValue::Object(f.into())
202    }
203}
204
205impl<K: Into<JsonString>, V: Into<JValue>> From<HashMap<K, V>> for JValue {
206    /// Convert map (with string keys) to `JValue::Object`.
207    ///
208    /// # Examples
209    ///
210    /// ```
211    /// use air_interpreter_value::JValue;
212    /// use std::collections::HashMap;
213    ///
214    /// let mut m = HashMap::<&str, &str>::new();
215    /// m.insert("Lorem", "ipsum");
216    /// let x: JValue = m.into();
217    /// ```
218    fn from(f: HashMap<K, V>) -> Self {
219        JValue::object_from_pairs(f)
220    }
221}
222
223impl<T: Into<JValue>> From<Vec<T>> for JValue {
224    /// Convert a `Vec` to `JValue::Array`.
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use air_interpreter_value::JValue;
230    ///
231    /// let v = vec!["lorem", "ipsum", "dolor"];
232    /// let x: JValue = v.into();
233    /// ```
234    fn from(f: Vec<T>) -> Self {
235        JValue::Array(f.into_iter().map(Into::into).collect())
236    }
237}
238
239impl<T: Clone + Into<JValue>> From<&[T]> for JValue {
240    /// Convert a slice to `JValue::Array`.
241    ///
242    /// # Examples
243    ///
244    /// ```
245    /// use air_interpreter_value::JValue;
246    ///
247    /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
248    /// let x: JValue = v.into();
249    /// ```
250    fn from(f: &[T]) -> Self {
251        JValue::Array(f.iter().cloned().map(Into::into).collect())
252    }
253}
254
255impl<T: Into<JValue>> FromIterator<T> for JValue {
256    /// Create a `JValue::Array` by collecting an iterator of array elements.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// use air_interpreter_value::JValue;
262    ///
263    /// let v = std::iter::repeat(42).take(5);
264    /// let x: JValue = v.collect();
265    /// ```
266    ///
267    /// ```
268    /// use air_interpreter_value::JValue;
269    ///
270    /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
271    /// let x: JValue = v.into_iter().collect();
272    /// ```
273    ///
274    /// ```
275    /// use std::iter::FromIterator;
276    /// use air_interpreter_value::JValue;
277    ///
278    /// let x: JValue = JValue::from_iter(vec!["lorem", "ipsum", "dolor"]);
279    /// ```
280    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
281        JValue::Array(iter.into_iter().map(Into::into).collect())
282    }
283}
284
285impl<K: Into<JsonString>, V: Into<JValue>> FromIterator<(K, V)> for JValue {
286    /// Create a `JValue::Object` by collecting an iterator of key-value pairs.
287    ///
288    /// # Examples
289    ///
290    /// ```
291    /// use air_interpreter_value::JValue;
292    ///
293    /// let v: Vec<_> = vec![("lorem", 40), ("ipsum", 2)];
294    /// let x: JValue = v.into_iter().collect();
295    /// ```
296    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
297        JValue::Object(Rc::new(
298            iter.into_iter()
299                .map(|(k, v)| (k.into(), v.into()))
300                .collect(),
301        ))
302    }
303}
304
305impl From<()> for JValue {
306    /// Convert `()` to `JValue::Null`.
307    ///
308    /// # Examples
309    ///
310    /// ```
311    /// use air_interpreter_value::JValue;
312    ///
313    /// let u = ();
314    /// let x: JValue = u.into();
315    /// ```
316    #[inline]
317    fn from((): ()) -> Self {
318        JValue::Null
319    }
320}
321
322impl<T> From<Option<T>> for JValue
323where
324    T: Into<JValue>,
325{
326    fn from(opt: Option<T>) -> Self {
327        match opt {
328            None => JValue::Null,
329            Some(value) => Into::into(value),
330        }
331    }
332}
333
334impl From<&serde_json::Value> for JValue {
335    fn from(value: &serde_json::Value) -> Self {
336        use serde_json::Value;
337
338        match value {
339            Value::Null => JValue::Null,
340            Value::Bool(b) => JValue::Bool(*b),
341            Value::Number(n) => JValue::Number(n.clone()),
342            Value::String(s) => JValue::String(s.as_str().into()),
343            Value::Array(a) => JValue::Array(a.iter().map(Into::into).collect()),
344            Value::Object(o) => {
345                let oo = Map::from_iter(o.into_iter().map(|(k, v)| (k.as_str().into(), v.into())));
346                JValue::Object(oo.into())
347            }
348        }
349    }
350}
351
352impl From<serde_json::Value> for JValue {
353    #[inline]
354    fn from(value: serde_json::Value) -> Self {
355        Self::from(&value)
356    }
357}