sonic_rs/value/from.rs
1use std::{borrow::Cow, fmt::Debug, str::FromStr};
2
3use faststr::FastStr;
4
5use super::{array::Array, node::ValueMut, object::Object};
6use crate::{serde::number::N, value::node::Value, Number};
7
8impl From<Number> for Value {
9 /// Convert `Number` to a `Value`.
10 ///
11 /// # Examples
12 ///
13 /// ```
14 /// use sonic_rs::{json, Number, Value};
15 ///
16 /// let x = Value::from(Number::from(7));
17 /// assert_eq!(x, json!(7));
18 /// ```
19 #[inline]
20 fn from(val: Number) -> Self {
21 match val.n {
22 N::PosInt(u) => Value::new_u64(u),
23 N::NegInt(i) => Value::new_i64(i),
24 N::Float(f) => unsafe { Value::new_f64_unchecked(f) },
25 }
26 }
27}
28
29macro_rules! impl_from_integer {
30 ($($ty:ident),*) => {
31 $(
32 impl From<$ty> for Value {
33 fn from(val: $ty) -> Self {
34 Into::<Number>::into(val).into()
35 }
36 }
37 )*
38 };
39 () => {};
40}
41
42impl_from_integer!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
43
44impl From<bool> for Value {
45 /// Convert `bool` to a boolean `Value`.
46 ///
47 /// # Examples
48 ///
49 /// ```
50 /// use sonic_rs::{JsonValueTrait, Value};
51 ///
52 /// let x: Value = true.into();
53 /// assert!(x.is_true());
54 /// ```
55 #[inline]
56 fn from(val: bool) -> Self {
57 Value::new_bool(val)
58 }
59}
60
61macro_rules! impl_from_str {
62 () => {};
63 ($($ty:ident),*) => {
64 $(
65 impl From<&$ty> for Value {
66 /// Convert a string type into a string `Value`. The string will be copied into the `Value`.
67 ///
68 /// # Performance
69 ///
70 /// If it is `&'static str`, recommend to use [`Value::from_static_str`] and it is zero-copy.
71 ///
72 #[inline]
73 fn from(val: &$ty) -> Self {
74 Value::copy_str(val)
75 }
76 }
77 )*
78 };
79}
80
81impl_from_str!(String, str);
82
83impl From<FastStr> for Value {
84 #[inline]
85 fn from(val: FastStr) -> Self {
86 Value::new_faststr(val)
87 }
88}
89
90impl From<&FastStr> for Value {
91 #[inline]
92 fn from(val: &FastStr) -> Self {
93 Value::new_faststr(val.clone())
94 }
95}
96
97impl<'a> From<Cow<'a, str>> for Value {
98 /// Convert copy-on-write string to a string `Value`.
99 ///
100 /// # Examples
101 ///
102 /// ```
103 /// use std::borrow::Cow;
104 ///
105 /// use sonic_rs::Value;
106 ///
107 /// let s1: Cow<str> = Cow::Borrowed("hello");
108 /// let x1 = Value::from(s1);
109 ///
110 /// let s2: Cow<str> = Cow::Owned("hello".to_string());
111 /// let x2 = Value::from(s2);
112 ///
113 /// assert_eq!(x1, x2);
114 /// ```
115 #[inline]
116 fn from(value: Cow<'a, str>) -> Self {
117 Into::<Self>::into(value.as_ref())
118 }
119}
120
121impl From<char> for Value {
122 /// Convert `char` to a string `Value`.
123 ///
124 /// # Examples
125 ///
126 /// ```
127 /// use sonic_rs::{json, Value};
128 ///
129 /// let c: char = '😁';
130 /// let x: Value = c.into();
131 /// assert_eq!(x, json!("😁"));
132 /// ```
133 #[inline]
134 fn from(val: char) -> Self {
135 Into::<Self>::into(&val.to_string())
136 }
137}
138
139impl<T: Into<Value>> From<Vec<T>> for Value {
140 /// Convert a `Vec` to a `Value`.
141 ///
142 /// # Examples
143 ///
144 /// ```
145 /// use sonic_rs::{json, Value};
146 ///
147 /// assert_eq!(Value::from(vec!["hi", "hello"]), json!(["hi", "hello"]));
148 ///
149 /// assert_eq!(Value::from(Vec::<i32>::new()), json!([]));
150 ///
151 /// assert_eq!(
152 /// Value::from(vec![json!(null), json!("hi")]),
153 /// json!([null, "hi"])
154 /// );
155 /// ```
156 #[inline]
157 fn from(val: Vec<T>) -> Self {
158 let mut arr = Array::with_capacity(val.len()).0;
159 for v in val {
160 arr.append_value(v.into());
161 }
162 arr
163 }
164}
165
166impl<T: Clone + Into<Value>, const N: usize> From<&[T; N]> for Value {
167 /// Convert a array reference `&[T; N]` to a `Value`.
168 ///
169 /// # Examples
170 ///
171 /// ```
172 /// use sonic_rs::{Value, json};
173 ///
174 /// let x = Value::from(&["hi", "hello"]);
175 ///
176 /// assert_eq!(x, json!(["hi", "hello"]));
177 #[inline]
178 fn from(val: &[T; N]) -> Self {
179 Into::<Value>::into(val.as_ref())
180 }
181}
182
183impl<T: Clone + Into<Value>> From<&[T]> for Value {
184 /// Convert a slice `&[T]` to a `Value`.
185 ///
186 /// # Examples
187 ///
188 /// ```
189 /// use sonic_rs::{json, Value};
190 ///
191 /// let x = Value::from(&["hi", "hello"][..]);
192 ///
193 /// assert_eq!(x, json!(["hi", "hello"]));
194 ///
195 /// let x: &[i32] = &[];
196 /// assert_eq!(Value::from(x), json!([]));
197 /// ```
198 fn from(val: &[T]) -> Self {
199 let mut arr = Array::with_capacity(val.len()).0;
200 for v in val {
201 arr.append_value(v.clone().into());
202 }
203 arr
204 }
205}
206
207impl From<()> for Value {
208 /// Convert `()` to `Value::Null`.
209 ///
210 /// # Examples
211 ///
212 /// ```
213 /// use sonic_rs::{JsonValueTrait, Value};
214 ///
215 /// assert!(Value::from(()).is_null());
216 /// ```
217 #[inline]
218 fn from(_: ()) -> Self {
219 Value::new_null()
220 }
221}
222
223impl<T> From<Option<T>> for Value
224where
225 T: Into<Value>,
226{
227 /// Convert `Option` to `Value::Null`.
228 ///
229 /// # Examples
230 ///
231 /// ```
232 /// use sonic_rs::{JsonValueTrait, Value};
233 ///
234 /// let u = Some(123);
235 /// let x = Value::from(u);
236 /// assert_eq!(x.as_i64(), u);
237 ///
238 /// let u = None;
239 /// let x: Value = u.into();
240 /// assert_eq!(x.as_i64(), u);
241 /// ```
242 #[inline]
243 fn from(opt: Option<T>) -> Self {
244 match opt {
245 None => Into::into(()),
246 Some(value) => Into::into(value),
247 }
248 }
249}
250
251impl FromStr for Value {
252 type Err = crate::Error;
253 /// Convert `&str` to `Value`. The `&str` will be copied into the `Value`.
254 ///
255 /// # Examples
256 ///
257 /// ```
258 /// use std::str::FromStr;
259 ///
260 /// use sonic_rs::{JsonValueTrait, Value};
261 ///
262 /// let x = Value::from_str("string").unwrap();
263 /// assert_eq!(x.as_str().unwrap(), "string");
264 /// ```
265 /// # Performance
266 ///
267 /// If it is `&'static str`, recommend to use [`Value::from_static_str`].
268 fn from_str(s: &str) -> Result<Self, Self::Err> {
269 Ok(Value::copy_str(s))
270 }
271}
272
273impl<'a, K: AsRef<str>, V: Clone + Into<Value>> FromIterator<(K, &'a V)> for Value {
274 /// Create a `Value` by collecting an iterator of key-value pairs.
275 /// The key will be copied into the `Value`.
276 ///
277 /// # Examples
278 ///
279 /// ```
280 /// use sonic_rs::{Value, json, object};
281 /// use std::collections::HashMap;
282 ///
283 /// let mut map = HashMap::new();
284 /// map.insert("sonic_rs", 40);
285 /// map.insert("json", 2);
286 ///
287 /// let x: Value = map.iter().collect();
288 /// assert_eq!(x, json!({"sonic_rs": 40, "json": 2}));
289 ///
290 /// let x: Value = Value::from_iter(&object!{"sonic_rs": 40, "json": 2});
291 /// assert_eq!(x, json!({"sonic_rs": 40, "json": 2}));
292 /// ```
293 fn from_iter<T: IntoIterator<Item = (K, &'a V)>>(iter: T) -> Self {
294 let mut obj = Object::with_capacity(0);
295 for (k, v) in iter.into_iter() {
296 obj.insert(&k, v.clone().into());
297 }
298 obj.0
299 }
300}
301
302impl<T: Into<Value>> FromIterator<T> for Value {
303 /// Create a `Value` by collecting an iterator of array elements.
304 ///
305 /// # Examples
306 ///
307 /// ```
308 /// use std::iter::FromIterator;
309 ///
310 /// use sonic_rs::{json, Value};
311 ///
312 /// let v = std::iter::repeat(6).take(3);
313 /// let x: Value = v.collect();
314 /// assert_eq!(x, json!([6, 6, 6]));
315 ///
316 /// let x = Value::from_iter(vec!["sonic_rs", "json", "serde"]);
317 /// assert_eq!(x, json!(["sonic_rs", "json", "serde"]));
318 /// ```
319 #[inline]
320 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
321 let mut arr = Array::with_capacity(0);
322 for v in iter.into_iter() {
323 arr.0.append_value(v.into());
324 }
325 arr.into()
326 }
327}
328
329//////////////////////////////////////////////////////////////////////////////
330
331impl<T: Into<Value>> From<Vec<T>> for Array {
332 /// Convert a `Vec` to a `Array`.
333 ///
334 /// # Examples
335 ///
336 /// ```
337 /// use sonic_rs::{array, value::Array};
338 ///
339 /// let v = vec!["hi", "hello"];
340 /// let x: Array = v.into();
341 /// assert_eq!(x, array!["hi", "hello"]);
342 /// ```
343 #[inline]
344 fn from(val: Vec<T>) -> Self {
345 Array(val.into())
346 }
347}
348
349impl<T: Clone + Into<Value>, const N: usize> From<&[T; N]> for Array {
350 /// Convert a array `&[T; N]` to a `Array`.
351 ///
352 /// # Examples
353 ///
354 /// ```
355 /// use sonic_rs::{array, Array};
356 ///
357 /// let v = &["hi", "hello"];
358 /// let x: Array = v.into();
359 /// assert_eq!(x, array!["hi", "hello"]);
360 /// ```
361 fn from(val: &[T; N]) -> Self {
362 Array(val.into())
363 }
364}
365
366impl<T: Into<Value>> FromIterator<T> for Array {
367 /// Create a `Array` by collecting an iterator of array elements.
368 ///
369 /// # Examples
370 ///
371 /// ```
372 /// use std::iter::FromIterator;
373 ///
374 /// use sonic_rs::{array, json, Array};
375 ///
376 /// let v = std::iter::repeat(6).take(3);
377 /// let x: Array = v.collect();
378 /// assert_eq!(x, json!([6, 6, 6]));
379 ///
380 /// let x = Array::from_iter(vec!["sonic_rs", "json", "serde"]);
381 /// assert_eq!(x, array!["sonic_rs", "json", "serde"]);
382 /// ```
383 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
384 let value = Value::from_iter(iter);
385 Array(value)
386 }
387}
388
389impl<T: Clone + Into<Value>> From<&[T]> for Array {
390 /// Convert a slice `&[T]` to a `Array`.
391 ///
392 /// # Examples
393 ///
394 /// ```
395 /// use sonic_rs::{array, value::Array};
396 ///
397 /// let v = &["hi", "hello"];
398 /// let x: Array = v.into();
399 /// assert_eq!(x, array!["hi", "hello"]);
400 /// ```
401 fn from(val: &[T]) -> Self {
402 let value = Into::<Value>::into(val);
403 Array(value)
404 }
405}
406
407//////////////////////////////////////////////////////////////////////////////
408
409impl<'a, K: AsRef<str>, V: Clone + Into<Value> + 'a> FromIterator<(K, &'a V)> for Object {
410 /// Create a `Object` by collecting an iterator of key-value pairs.
411 ///
412 /// # Examples
413 ///
414 /// ```
415 /// use std::collections::HashMap;
416 ///
417 /// use sonic_rs::{object, Object, Value};
418 ///
419 /// let mut map = HashMap::new();
420 /// map.insert("sonic_rs", 40);
421 /// map.insert("json", 2);
422 ///
423 /// let x: Object = map.iter().collect();
424 /// assert_eq!(x, object! {"sonic_rs": 40, "json": 2});
425 ///
426 /// let x = Object::from_iter(&object! {"sonic_rs": 40, "json": 2});
427 /// assert_eq!(x, object! {"sonic_rs": 40, "json": 2});
428 /// ```
429 #[inline]
430 fn from_iter<T: IntoIterator<Item = (K, &'a V)>>(iter: T) -> Self {
431 let value = Value::from_iter(iter);
432 Object(value)
433 }
434}
435
436impl<'a, T: Clone + Into<Value> + 'a> Extend<&'a T> for Array {
437 /// Extend a `Array` with the contents of an iterator.
438 ///
439 /// # Examples
440 ///
441 /// ```
442 /// use sonic_rs::{array, json, Array};
443 /// let mut arr = array![];
444 ///
445 /// // array extend from a slice &[i32]
446 /// arr.extend(&[1, 2, 3]);
447 /// assert_eq!(arr, array![1, 2, 3]);
448 ///
449 /// arr.extend(&Array::default());
450 /// assert_eq!(arr, array![1, 2, 3]);
451 ///
452 /// // array extend from other array
453 /// arr.extend(&array![4, 5, 6]);
454 /// assert_eq!(arr, array![1, 2, 3, 4, 5, 6]);
455 /// ```
456 #[inline]
457 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
458 if let ValueMut::Array(value) = self.0.as_mut() {
459 for v in iter.into_iter() {
460 value.push(v.clone().into());
461 }
462 } else {
463 unreachable!("should not happened")
464 }
465 }
466}
467
468impl<'a, K: AsRef<str> + ?Sized, V: Clone + Debug + Into<Value> + 'a> Extend<(&'a K, &'a V)>
469 for Object
470{
471 /// Extend a `Object` with the contents of an iterator.
472 ///
473 /// # Examples
474 ///
475 /// ```
476 /// use std::collections::HashMap;
477 ///
478 /// use sonic_rs::{json, object, Object, Value};
479 ///
480 /// let mut obj = object![];
481 /// let mut map: HashMap<&str, Value> = {
482 /// let mut map = HashMap::new();
483 /// map.insert("sonic", json!(40));
484 /// map.insert("rs", json!(null));
485 /// map
486 /// };
487 ///
488 /// obj.extend(&map);
489 /// assert_eq!(obj, object! {"sonic": 40, "rs": null});
490 ///
491 /// obj.extend(&object! {"object": [1, 2, 3]});
492 /// assert_eq!(obj, object! {"sonic": 40, "rs": null, "object": [1, 2, 3]});
493 /// ```
494 fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
495 for (k, v) in iter.into_iter() {
496 self.insert(k.as_ref(), v.clone().into());
497 }
498 }
499}
500
501impl From<Array> for Value {
502 #[inline]
503 fn from(val: Array) -> Self {
504 val.0
505 }
506}
507
508impl From<Object> for Value {
509 #[inline]
510 fn from(val: Object) -> Self {
511 val.0
512 }
513}
514
515#[cfg(test)]
516mod test {
517
518 use std::collections::HashMap;
519
520 use crate::{array, json, object, value::node::Value};
521
522 #[test]
523 fn test_from() {
524 let a1 = json!([1, 2, 3]);
525 let a2: Value = vec![1, 2, 3].into();
526 assert_eq!(a1, a2);
527 let v = Value::from(vec![json!("hi")]);
528 assert_eq!(v, json!(["hi"]));
529 }
530
531 #[test]
532 fn test_extend_array() {
533 let mut a1 = array![1, 2, 3];
534 let mut b1 = a1.clone();
535
536 let a2 = vec![4, 5, 6];
537 let a3 = array![4, 5, 6];
538 a1.extend(&a2);
539 b1.extend(&a3);
540 assert_eq!(a1, b1);
541 }
542
543 #[test]
544 fn test_extend_object() {
545 let mut obj = object![];
546 let mut map: HashMap<&str, Value> = HashMap::new();
547
548 map.insert("sonic_rs", json!(40));
549 map.insert("json", "hi".into());
550 obj.extend(map.iter());
551 }
552
553 #[test]
554 fn test_from_iter() {
555 use std::{collections::HashMap, iter::FromIterator};
556
557 use crate::{json, Value};
558
559 let mut map = HashMap::new();
560 map.insert("sonic_rs", 40);
561 map.insert("json", 2);
562
563 let x: Value = map.iter().collect();
564 assert_eq!(x, json!({"sonic_rs": 40, "json": 2}));
565
566 let v = std::iter::repeat_n(6, 3);
567 let x1: Vec<_> = v.collect();
568 dbg!(x1);
569 let v = std::iter::repeat_n(6, 3);
570 let x: Value = v.collect();
571 assert_eq!(x, json!([6, 6, 6]));
572
573 let x = Value::from_iter(vec!["sonic_rs", "json", "serde"]);
574 assert_eq!(x, json!(["sonic_rs", "json", "serde"]));
575 }
576}