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}