jsondata/
json.rs

1// Copyright © 2019 R Pratap Chakravarthy. All rights reserved.
2
3use std::cmp::{Ord, Ordering, PartialOrd};
4use std::convert::{From, TryFrom, TryInto};
5use std::fmt::{self, Display, Write};
6use std::{default::Default, ops::RangeBounds, str::FromStr};
7
8use crate::num::{Floating, Integral};
9use crate::{jptr, lex::Lex, ops, parse::parse_value, property::Property, Error, Result};
10
11// TODO: test case for all combination for JsonSerialize,
12// refer to examples/macro.rs
13
14/// Json type implements JavaScript Object Notation as per specification
15/// [RFC-8259](https://tools.ietf.org/html/rfc8259).
16///
17/// * JSON scalar types - Null, Number, Boolean, String, are supported.
18/// * JSON container types - Array, Object, are supported.
19/// * JSON numbers can be 128-bit integers or 64-bit floating point.
20/// * When document is known to contain lot of numbers and only one of
21///   them needs to be extracted, parsing the entire document can be
22///   inefficient just to get that one field. Numbers are implemented
23///   with deferred conversion, using ``Integral`` and ``Floating`` types.
24/// * Arrays are implemented as vector of Json values Vec<[Json]>.
25/// * Objects are implemented as vector of properties, Vec<[Property]>,
26///   where each property is a tuple of (key, value). Here key is [String]
27///   type and value is [Json] type.
28///
29/// [Json] enum type has documented variants and undocumented variants.
30/// Applications, when matching with Json, must use the catch-all variant:
31/// ```ignore
32/// match json {
33///     Json::Null => // handle null,
34///     Json::Bool(b) => // handle bool,
35///     Json::Integer(i) => // handle integer,
36///     Json::Float(f) => // handle float,
37///     Json::String(s) => // handle string,
38///     Json::Array(a) => // handle array,
39///     Json::Object(o) => // handle object,
40///     _ => // catch all.
41/// }
42/// ```
43///
44///
45/// **Parsing JSON text**:
46/// ```
47/// let json: jsondata::Json = "10".parse().unwrap();
48/// ```
49///
50/// return a [Json] enum type.
51///
52/// **Converting Rust native types to [Json] enum**:
53///
54/// Json supports conversion from [bool], [u8], [i8], [u16], [i16], [u32],
55/// [i32], [u64], [i64], [i128], [i128], [f32], [f64], [String], [str],
56/// Vec<[Json]> and Vec<[Property]> types using the [From] trait.
57/// Converting from u128 shall cause panic if value is larger than
58/// `i128::max()`.
59///
60/// ```
61/// let json = jsondata::Json::from(10);
62/// let json = jsondata::Json::from(true);
63/// let json = jsondata::Json::from("hello world");
64/// ```
65///
66/// On the other direction, [Json] enum can be converted to Rust native
67/// types using accessor methods,
68/// - is_null() to check whether [Json] is Null
69/// - to_bool(), to_integer(), to_float(), to_string() methods return the
70///   underlying value as Option<`T`> where `T` is [bool] or [i128] or [f64]
71///   or [String].
72/// - to_array(), return JSON array as Vec<[Json]>.
73/// - to_object(), return JSON object as Vec<[Property]>.
74/// - Refer to API list and conversion traits implementation for more details.
75///
76/// Some of the properties implemented for [Json] are:
77/// - [Json] implements [total ordering].
78/// - Default value for Json is Null.
79/// - Json types are clone-able but do not implement [Copy].
80/// - [Json] value can be serialized into JSON format using [Display] trait.
81///
82/// **Panics**
83///
84/// [Json] implements AsRef and AsMut traits for [str], Vec<[Json]>,
85/// Vec<[Property]> types. This means, call to as_ref() and as_mut() shall
86/// panic when underlying Json variant do not match with expected type.
87///
88/// [string]: std::string::String
89/// [total ordering]: https://en.wikipedia.org/wiki/Total_order
90#[derive(Clone, Debug)]
91pub enum Json {
92    Null,
93    Bool(bool),
94    Integer(Integral),
95    Float(Floating),
96    String(String),
97    Array(Vec<Json>),
98    Object(Vec<Property>),
99    // Hidden variants
100    #[doc(hidden)]
101    __Error(Error),
102    #[doc(hidden)]
103    __Minbound,
104    #[doc(hidden)]
105    __Maxbound,
106}
107
108/// Implementation provides methods to construct and validate Json values.
109impl Json {
110    /// Construct [Json] from [bool], [i128], [f64], [String], [str],
111    /// [Vec].
112    ///
113    /// Array can be composed as:
114    ///
115    /// ```
116    /// use jsondata::Json;
117    ///
118    /// let mut js = Json::new::<Vec<Json>>(Vec::new());
119    /// js.append("", Json::new(10));
120    /// js.append("", Json::new("hello world".to_string()));
121    /// ```
122    ///
123    /// It is also possible to construct the vector of Json outside
124    /// the append() method, and finally use Json::new() to construct
125    /// the array.
126    ///
127    /// Object can be composed as:
128    ///
129    /// ```
130    /// use jsondata::{Json, Property};
131    ///
132    /// let mut js = Json::new::<Vec<Property>>(Vec::new());
133    /// js.set("/key1", Json::new(10));
134    /// js.set("/key2", Json::new(true));
135    /// ```
136    ///
137    /// It is also possible to construct the vector of properties outside
138    /// the set() method, and finally use Json::new() to construct
139    /// the object.
140    pub fn new<T>(value: T) -> Json
141    where
142        Self: From<T>,
143    {
144        Json::from(value)
145    }
146
147    /// Minbound return a Json value that sort before every other [Json] type.
148    #[allow(dead_code)]
149    pub(crate) fn minbound() -> Json {
150        Json::__Minbound
151    }
152
153    /// Maxbound return a Json value that sort after every other [Json] type.
154    #[allow(dead_code)]
155    pub(crate) fn maxbound() -> Json {
156        Json::__Maxbound
157    }
158
159    /// Validate parts of JSON text that are not yet parsed. Typically,
160    /// when used in database context, JSON documents are validated once
161    /// but parsed multiple times.
162    pub fn validate(&mut self) -> Result<()> {
163        use crate::json::Json::{Array, Float, Integer, Object};
164
165        match self {
166            Array(items) => {
167                for item in items.iter_mut() {
168                    item.validate()?
169                }
170            }
171            Object(props) => {
172                for prop in props.iter_mut() {
173                    prop.as_mut_value().validate()?
174                }
175            }
176            Integer(item) => {
177                item.compute()?;
178            }
179            Float(item) => {
180                item.compute()?;
181            }
182            _ => (),
183        };
184        Ok(())
185    }
186
187    /// Compute parses unparsed text and convert them into numbers.
188    /// When a JSON document is parsed once but operated on multiple
189    /// times it is better to call compute for better performance.
190    ///
191    /// ```
192    /// use jsondata::Json;
193    ///
194    /// let text = r#"[null,true,false,10,"true"]"#;
195    /// let mut json: Json = text.parse().unwrap();
196    /// json.compute();
197    ///
198    /// // perform lookup and arithmetic operations on parsed document.
199    /// ```
200    pub fn compute(&mut self) -> Result<()> {
201        use crate::json::Json::{Array, Float, Integer, Object};
202
203        match self {
204            Array(items) => {
205                for item in items.iter_mut() {
206                    item.compute()?
207                }
208            }
209            Object(props) => {
210                for prop in props.iter_mut() {
211                    prop.as_mut_value().compute()?
212                }
213            }
214            Integer(item) => {
215                item.compute()?;
216            }
217            Float(item) => {
218                item.compute()?;
219            }
220            _ => (),
221        };
222        Ok(())
223    }
224
225    pub fn type_name(&self) -> String {
226        match self {
227            Json::Null => "null".to_string(),
228            Json::Bool(_) => "bool".to_string(),
229            Json::Integer(_) => "integer".to_string(),
230            Json::Float(_) => "float".to_string(),
231            Json::String(_) => "string".to_string(),
232            Json::Array(_) => "array".to_string(),
233            Json::Object(_) => "object".to_string(),
234            Json::__Error(_) => "error".to_string(),
235            Json::__Minbound => "minbound".to_string(),
236            Json::__Maxbound => "maxbound".to_string(),
237        }
238    }
239}
240
241/// Implementation provides CRUD access into [Json] document using
242/// [Json Pointer]. For all methods,
243///
244/// * Path must be valid JSON Pointer.
245/// * Path fragment must be valid key if parent container is an object.
246/// * Path fragment must be a number index if parent container is an array.
247///
248/// [JSON Pointer]: https://tools.ietf.org/html/rfc6901
249impl Json {
250    /// Get a json field, within the document, locatable by ``path``.
251    pub fn get(&self, path: &str) -> Result<Json> {
252        if path.is_empty() {
253            Ok(self.clone())
254        } else {
255            let path = jptr::fix_prefix(path)?;
256            let (json, key) = jptr::lookup_ref(self, path)?;
257            Ok(json[key.as_str()].to_result()?.clone())
258        }
259    }
260
261    /// Set a json field, within the document, locatable by ``path``.
262    pub fn set(&mut self, path: &str, value: Json) -> Result<()> {
263        if path.is_empty() {
264            return Ok(());
265        }
266
267        let path = jptr::fix_prefix(path)?;
268
269        let (json, frag) = jptr::lookup_mut(self, path)?;
270        match json {
271            Json::Array(arr) => match frag.parse::<usize>() {
272                Ok(n) => {
273                    if n >= arr.len() {
274                        err_at!(IndexOutofBound, msg: "{}", n)
275                    } else {
276                        arr[n] = value;
277                        Ok(())
278                    }
279                }
280                Err(err) => err_at!(InvalidIndex, msg: "{}", err),
281            },
282            Json::Object(props) => {
283                match props.binary_search_by(|p| p.as_key().cmp(&frag)) {
284                    Ok(n) => {
285                        props[n].set_value(value);
286                        Ok(())
287                    }
288                    Err(n) => {
289                        props.insert(n, Property::new(frag, value));
290                        Ok(())
291                    }
292                }
293            }
294            _ => err_at!(InvalidContainer, msg: "{}", json.type_name()),
295        }
296    }
297
298    /// Delete a JSON field, within the document, locatable by ``path``.
299    pub fn delete(&mut self, path: &str) -> Result<()> {
300        if path.is_empty() {
301            return Ok(());
302        }
303
304        let path = jptr::fix_prefix(path)?;
305
306        let (json, frag) = jptr::lookup_mut(self, path)?;
307        match json {
308            Json::Array(arr) => match frag.parse::<usize>() {
309                Ok(n) => {
310                    if n >= arr.len() {
311                        err_at!(IndexOutofBound, msg: "{}", n)
312                    } else {
313                        arr.remove(n);
314                        Ok(())
315                    }
316                }
317                Err(err) => err_at!(InvalidIndex, msg: "{}", err),
318            },
319            Json::Object(props) => {
320                match props.binary_search_by(|p| p.as_key().cmp(&frag)) {
321                    Ok(n) => {
322                        props.remove(n);
323                        Ok(())
324                    }
325                    Err(_) => err_at!(PropertyNotFound, msg: "{}", frag),
326                }
327            }
328            _ => err_at!(InvalidContainer, msg: "{}", json.type_name()),
329        }
330    }
331
332    /// Append a string or array to a JSON field within the document that is
333    /// either a string or array.
334    pub fn append(&mut self, path: &str, value: Json) -> Result<()> {
335        if path.is_empty() {
336            return Ok(());
337        }
338        let path = jptr::fix_prefix(path)?;
339
340        let (json, frag) = jptr::lookup_mut(self, path)?;
341        match ops::index_mut(json, frag.as_str())? {
342            Json::String(j) => {
343                if let Json::String(s) = value {
344                    j.push_str(&s);
345                    Ok(())
346                } else {
347                    err_at!(AppendString, msg: "{}", value.type_name())
348                }
349            }
350            Json::Array(arr) => {
351                let n = arr.len();
352                arr.insert(n, value);
353                Ok(())
354            }
355            _ => err_at!(InvalidContainer, msg: "{}", json.type_name()),
356        }
357    }
358
359    /// Range operation on Json array,
360    ///
361    /// * Range              ``[start..end]``.
362    /// * RangeFrom          ``[start..]``.
363    /// * RangeFull          ``[..]``.
364    /// * RangeInclusive     ``[start..=end]``.
365    /// * RangeTo            ``[..end]``.
366    /// * RangeToInclusive   ``[..=end]``.
367    ///
368    /// If range is called on non array Json, returns a Json Error.
369    pub fn range<R>(&self, range: R) -> Json
370    where
371        R: RangeBounds<isize>,
372    {
373        use std::ops::Bound::{Excluded, Included, Unbounded};
374
375        match self {
376            Json::__Error(_) => self.clone(),
377            Json::Array(arr) => {
378                let (start, s) = match range.start_bound() {
379                    Included(n) => (ops::normalized_offset(*n, arr.len()), *n),
380                    Excluded(n) => (ops::normalized_offset((*n) + 1, arr.len()), *n),
381                    Unbounded => (Some(0), 0),
382                };
383                let (end, e) = match range.end_bound() {
384                    Included(n) => (ops::normalized_offset((*n) + 1, arr.len()), *n),
385                    Excluded(n) => (ops::normalized_offset(*n, arr.len()), *n),
386                    Unbounded => (Some(arr.len()), isize::try_from(arr.len()).unwrap()),
387                };
388                match (start, end) {
389                    (Some(start), Some(end)) => Json::Array(arr[start..end].to_vec()),
390                    (None, _) => Json::__Error(
391                        (err_at!(IndexOutofBound, msg: "{}", s) as Result<()>)
392                            .unwrap_err(),
393                    ),
394                    (_, None) => Json::__Error(
395                        (err_at!(IndexOutofBound, msg: "{}", e) as Result<()>)
396                            .unwrap_err(),
397                    ),
398                }
399            }
400            _ => Json::__Error(
401                (err_at!(NotAnArray, msg: "{}", self) as Result<()>).unwrap_err(),
402            ),
403        }
404    }
405}
406
407/// Implementation clones underlying type for each Json variant.
408/// The return value is always an [Option] because JSON
409/// follows a schema-less data representation.
410impl Json {
411    pub fn is_null(&self) -> bool {
412        matches!(self, Json::Null)
413    }
414
415    pub fn to_bool(&self) -> Option<bool> {
416        match self {
417            Json::Bool(s) => Some(*s),
418            _ => None,
419        }
420    }
421
422    pub fn to_integer(&self) -> Option<i128> {
423        match self {
424            Json::Integer(item) => item.integer(),
425            _ => None,
426        }
427    }
428
429    pub fn to_float(&self) -> Option<f64> {
430        match self {
431            Json::Float(item) => item.float(),
432            Json::Integer(item) => item.float(),
433            _ => None,
434        }
435    }
436
437    pub fn as_str(&self) -> Option<&str> {
438        match self {
439            Json::String(s) => Some(s),
440            _ => None,
441        }
442    }
443
444    pub fn to_array(&self) -> Option<Vec<Json>> {
445        match self {
446            Json::Array(arr) => Some(arr.clone()),
447            _ => None,
448        }
449    }
450
451    pub fn to_object(&self) -> Option<Vec<Property>> {
452        match self {
453            Json::Object(obj) => Some(obj.clone()),
454            _ => None,
455        }
456    }
457
458    pub fn is_error(&self) -> bool {
459        matches!(self, Json::__Error(_))
460    }
461
462    pub fn to_error(&self) -> Option<Error> {
463        match self {
464            Json::__Error(err) => Some(err.clone()),
465            _ => None,
466        }
467    }
468
469    pub fn to_result(&self) -> Result<&Json> {
470        match self {
471            Json::__Error(err) => Err(err.clone()),
472            _ => Ok(self),
473        }
474    }
475}
476
477impl Json {
478    pub(crate) fn to_integer_result(&self) -> Result<i128> {
479        match self {
480            Json::Integer(item) => item.integer_result(),
481            _ => err_at!(InvalidType, msg: "not an integer"),
482        }
483    }
484
485    pub(crate) fn to_float_result(&self) -> Result<f64> {
486        match self {
487            Json::Float(item) => item.float_result(),
488            _ => err_at!(InvalidType, msg: "not a float"),
489        }
490    }
491}
492
493impl Eq for Json {}
494
495impl PartialEq for Json {
496    fn eq(&self, other: &Json) -> bool {
497        use crate::Json::{Array, Bool, Float, Integer, Null, Object, String as S};
498        use std::i128;
499
500        match (self, other) {
501            (Null, Null) => true,
502            (Bool(a), Bool(b)) => a == b,
503            (Integer(_), Integer(_)) => self.to_integer() == other.to_integer(),
504            (Integer(a), Float(b)) => match (a.integer(), b.float()) {
505                (Some(x), Some(y)) => {
506                    let num = y as i128;
507                    if num == i128::MIN || num == i128::MAX || y.is_nan() {
508                        return false;
509                    }
510                    x == num
511                }
512                _ => false,
513            },
514            (Float(_), Float(_)) => {
515                let (fs, fo) = (self.to_float().unwrap(), other.to_float().unwrap());
516                if fs.is_finite() && fo.is_finite() {
517                    return fs == fo;
518                } else if fs.is_nan() && fo.is_nan() {
519                    return true;
520                } else if fs.is_infinite() && fo.is_infinite() {
521                    return fs.is_sign_positive() == fo.is_sign_positive();
522                }
523                false
524            }
525            (Float(a), Integer(b)) => match (a.float(), b.integer()) {
526                (Some(x), Some(y)) => {
527                    let num = x as i128;
528                    if num == i128::MIN || num == i128::MAX || x.is_nan() {
529                        return false;
530                    }
531                    y == num
532                }
533                _ => false,
534            },
535            (S(a), S(b)) => a == b,
536            (Array(a), Array(b)) => a == b,
537            (Object(a), Object(b)) => a == b,
538            // handle boundaries
539            (Json::__Minbound, Json::__Minbound) => true,
540            (Json::__Maxbound, Json::__Maxbound) => true,
541            // catch all
542            _ => false,
543        }
544    }
545}
546
547impl PartialOrd for Json {
548    fn partial_cmp(&self, other: &Json) -> Option<Ordering> {
549        Some(self.cmp(other))
550    }
551}
552
553impl Ord for Json {
554    fn cmp(&self, other: &Json) -> Ordering {
555        use crate::Json::{Array, Bool, Float, Integer, Null, Object, String as S};
556
557        match (self, other) {
558            // typically we assume that value at same position is same type.
559            (Null, Null) => Ordering::Equal,
560            (Bool(a), Bool(b)) => {
561                if (*a) == (*b) {
562                    Ordering::Equal
563                } else if !(*a) {
564                    Ordering::Less
565                } else {
566                    Ordering::Greater
567                }
568            }
569            (Integer(a), Integer(b)) => {
570                let (x, y) = (a.integer().unwrap(), b.integer().unwrap());
571                x.cmp(&y)
572            }
573            (Float(a), Float(b)) => {
574                let (fs, fo) = (a.float().unwrap(), b.float().unwrap());
575                if fs.is_finite() && fo.is_finite() {
576                    if fs < fo {
577                        Ordering::Less
578                    } else if fs > fo {
579                        Ordering::Greater
580                    } else if fs == 0.0 || fo == 0.0 {
581                        if fs.is_sign_negative() {
582                            Ordering::Less
583                        } else if fo.is_sign_negative() {
584                            Ordering::Greater
585                        } else {
586                            Ordering::Equal
587                        }
588                    } else {
589                        Ordering::Equal
590                    }
591                } else {
592                    let is = if fs.is_infinite() { fs.signum() as i32 } else { 2 };
593                    let io = if fo.is_infinite() { fo.signum() as i32 } else { 2 };
594                    is.cmp(&io)
595                }
596            }
597            (Integer(a), Float(b)) => match (a.integer(), b.float()) {
598                (Some(x), Some(y)) => x.cmp(&(y as i128)),
599                (Some(_), None) => Ordering::Greater,
600                (None, Some(_)) => Ordering::Less,
601                (None, None) => Ordering::Equal,
602            },
603            (Float(a), Integer(b)) => match (a.float(), b.integer()) {
604                (Some(x), Some(y)) => (x as i128).cmp(&y),
605                (Some(_), None) => Ordering::Greater,
606                (None, Some(_)) => Ordering::Less,
607                (None, None) => Ordering::Equal,
608            },
609            (S(a), S(b)) => a.cmp(b),
610            (Array(this), Array(that)) => {
611                for (i, a) in this.iter().enumerate() {
612                    if i == that.len() {
613                        return Ordering::Greater;
614                    }
615                    let cmp = a.cmp(&that[i]);
616                    if cmp != Ordering::Equal {
617                        return cmp;
618                    }
619                }
620                if this.len() == that.len() {
621                    Ordering::Equal
622                } else {
623                    Ordering::Less
624                }
625            }
626            (Object(this), Object(that)) => {
627                for (i, a) in this.iter().enumerate() {
628                    if i == that.len() {
629                        return Ordering::Greater;
630                    }
631                    let cmp = a.as_key().cmp(that[i].as_key());
632                    if cmp != Ordering::Equal {
633                        return cmp;
634                    }
635                    let cmp = a.as_value().cmp(that[i].as_value());
636                    if cmp != Ordering::Equal {
637                        return cmp;
638                    }
639                }
640                if this.len() == that.len() {
641                    Ordering::Equal
642                } else {
643                    Ordering::Less
644                }
645            }
646            // handle error cases, error variants sort at the end.
647            (_, Json::__Error(_)) => Ordering::Less,
648            (Json::__Error(_), _) => Ordering::Greater,
649            // handle boundaries
650            (Json::__Minbound, Json::__Minbound) => Ordering::Equal,
651            (Json::__Maxbound, Json::__Maxbound) => Ordering::Equal,
652            (Json::__Minbound, _) => Ordering::Less,
653            (Json::__Maxbound, _) => Ordering::Greater,
654            (_, Json::__Minbound) => Ordering::Greater,
655            (_, Json::__Maxbound) => Ordering::Less,
656            // handle cases of mixed types.
657            (Null, _) => Ordering::Less,
658            (_, Null) => Ordering::Greater,
659            (Bool(_), _) => Ordering::Less,
660            (_, Bool(_)) => Ordering::Greater,
661            (Integer(_), _) => Ordering::Less,
662            (_, Integer(_)) => Ordering::Greater,
663            (Float(_), _) => Ordering::Less,
664            (_, Float(_)) => Ordering::Greater,
665            (S(_), _) => Ordering::Less,
666            (_, S(_)) => Ordering::Greater,
667            (Array(_), _) => Ordering::Less,
668            (_, Array(_)) => Ordering::Greater,
669        }
670    }
671}
672
673impl Default for Json {
674    fn default() -> Json {
675        Json::Null
676    }
677}
678
679macro_rules! convert_nums {
680    (bool, $var:ident, $method:ident) => {
681        impl From<bool> for Json {
682            fn from(val: bool) -> Json {
683                Json::$var(val.into())
684            }
685        }
686    };
687    (f32, $var:ident, $method:ident) => {
688        impl From<f32> for Json {
689            fn from(val: f32) -> Json {
690                Json::$var(val.into())
691            }
692        }
693        impl TryFrom<Json> for f32 {
694            type Error = Error;
695
696            fn try_from(val: Json) -> Result<f32> {
697                match val.$method() {
698                    Some(val) => Ok(val as f32),
699                    None => err_at!(InvalidType, msg: "{}", val.type_name()),
700                }
701            }
702        }
703    };
704    ($from:ty, $var:ident, $method:ident) => {
705        impl From<$from> for Json {
706            fn from(val: $from) -> Json {
707                Json::$var(val.into())
708            }
709        }
710        impl TryFrom<Json> for $from {
711            type Error = Error;
712
713            fn try_from(val: Json) -> Result<$from> {
714                match val.$method() {
715                    Some(val) => match val.try_into() {
716                        Ok(val) => Ok(val),
717                        Err(err) => err_at!(InvalidNumber, msg: "{}", err),
718                    },
719                    None => err_at!(InvalidType, msg: "{}", val.type_name()),
720                }
721            }
722        }
723    };
724}
725
726convert_nums!(bool, Bool, to_bool);
727convert_nums!(u8, Integer, to_integer);
728convert_nums!(i8, Integer, to_integer);
729convert_nums!(u16, Integer, to_integer);
730convert_nums!(i16, Integer, to_integer);
731convert_nums!(u32, Integer, to_integer);
732convert_nums!(i32, Integer, to_integer);
733convert_nums!(u64, Integer, to_integer);
734convert_nums!(i64, Integer, to_integer);
735convert_nums!(u128, Integer, to_integer);
736convert_nums!(i128, Integer, to_integer);
737convert_nums!(usize, Integer, to_integer);
738convert_nums!(isize, Integer, to_integer);
739convert_nums!(f32, Float, to_float);
740convert_nums!(f64, Float, to_float);
741
742impl From<String> for Json {
743    fn from(val: String) -> Json {
744        Json::String(val)
745    }
746}
747
748impl From<&str> for Json {
749    fn from(val: &str) -> Json {
750        Json::String(val.to_string())
751    }
752}
753
754impl TryFrom<Json> for String {
755    type Error = Error;
756
757    fn try_from(val: Json) -> Result<String> {
758        match val.as_str() {
759            Some(s) => Ok(s.to_string()),
760            None => err_at!(InvalidType, msg: "{}", val.type_name()),
761        }
762    }
763}
764
765impl From<Vec<Property>> for Json {
766    fn from(val: Vec<Property>) -> Json {
767        let mut obj = Json::Object(vec![]);
768        val.into_iter().for_each(|item| insert(&mut obj, item));
769        obj
770    }
771}
772
773impl TryFrom<Json> for Vec<Property> {
774    type Error = Error;
775
776    fn try_from(val: Json) -> Result<Vec<Property>> {
777        match val.to_object() {
778            Some(val) => Ok(val),
779            None => err_at!(InvalidType, msg: "{}", val.type_name()),
780        }
781    }
782}
783
784impl<T> From<(T,)> for Json
785where
786    Json: From<T>,
787{
788    fn from(val: (T,)) -> Json {
789        Json::Array(vec![Json::from(val.0)])
790    }
791}
792
793impl<T> TryFrom<Json> for (T,)
794where
795    T: TryFrom<Json, Error = Error>,
796{
797    type Error = Error;
798
799    fn try_from(val: Json) -> Result<(T,)> {
800        match val.to_array() {
801            Some(val) if val.len() == 1 => Ok((T::try_from(val[0].clone())?,)),
802            Some(v) => err_at!(
803                InvalidType,
804                msg: "{} tuple-arity-1 {}", val.type_name(), v.len()
805            ),
806            None => err_at!(InvalidType, msg: "{}", val.type_name()),
807        }
808    }
809}
810
811impl<U, V> From<(U, V)> for Json
812where
813    Json: From<U> + From<V>,
814{
815    fn from(val: (U, V)) -> Json {
816        let inner = vec![Json::from(val.0), Json::from(val.1)];
817        Json::Array(inner)
818    }
819}
820
821impl<U, V> TryFrom<Json> for (U, V)
822where
823    U: TryFrom<Json, Error = Error>,
824    V: TryFrom<Json, Error = Error>,
825{
826    type Error = Error;
827
828    fn try_from(val: Json) -> Result<(U, V)> {
829        match val.to_array() {
830            Some(val) if val.len() == 2 => {
831                Ok((U::try_from(val[0].clone())?, V::try_from(val[1].clone())?))
832            }
833            Some(v) => err_at!(
834                InvalidType,
835                msg: "{} tuple-arity-2 {}", val.type_name(), v.len()
836            ),
837            None => err_at!(InvalidType, msg: "{}", val.type_name()),
838        }
839    }
840}
841
842impl<A, B, C> From<(A, B, C)> for Json
843where
844    Json: From<A> + From<B> + From<C>,
845{
846    fn from(val: (A, B, C)) -> Json {
847        let inner = vec![Json::from(val.0), Json::from(val.1), Json::from(val.2)];
848        Json::Array(inner)
849    }
850}
851
852impl<A, B, C> TryFrom<Json> for (A, B, C)
853where
854    A: TryFrom<Json, Error = Error>,
855    B: TryFrom<Json, Error = Error>,
856    C: TryFrom<Json, Error = Error>,
857{
858    type Error = Error;
859
860    fn try_from(val: Json) -> Result<(A, B, C)> {
861        match val.to_array() {
862            Some(val) if val.len() == 3 => Ok((
863                A::try_from(val[0].clone())?,
864                B::try_from(val[1].clone())?,
865                C::try_from(val[2].clone())?,
866            )),
867            Some(v) => err_at!(
868                InvalidType,
869                msg: "{} tuple-arity-3 {}", val.type_name(), v.len()
870            ),
871            None => err_at!(InvalidType, msg: "{}", val.type_name()),
872        }
873    }
874}
875
876impl<T> From<Vec<T>> for Json
877where
878    Json: From<T>,
879{
880    fn from(val: Vec<T>) -> Json {
881        let inner: Vec<Json> = val.into_iter().map(|v| Json::from(v)).collect();
882        Json::Array(inner)
883    }
884}
885
886impl<T> TryFrom<Json> for Vec<T>
887where
888    T: TryFrom<Json, Error = Error>,
889{
890    type Error = Error;
891
892    fn try_from(val: Json) -> Result<Vec<T>> {
893        match val.to_array() {
894            Some(val) => {
895                let mut out = vec![];
896                for v in val.into_iter() {
897                    out.push(T::try_from(v)?);
898                }
899                Ok(out)
900            }
901            None => err_at!(InvalidType, msg: "{}", val.type_name()),
902        }
903    }
904}
905
906impl From<Json> for bool {
907    fn from(val: Json) -> bool {
908        use crate::json::Json::String as S;
909        use crate::json::Json::{Array, Bool, Float, Integer, Null, Object};
910
911        match val {
912            Null => false,
913            Bool(v) => v,
914            Integer(_) => val.to_integer().unwrap() != 0,
915            Float(_) => val.to_float().unwrap() != 0.0,
916            S(s) => !s.is_empty(),
917            Array(a) => !a.is_empty(),
918            Object(o) => !o.is_empty(),
919            Json::__Error(_) => false,
920            Json::__Minbound => true,
921            Json::__Maxbound => true,
922        }
923    }
924}
925
926impl FromStr for Json {
927    type Err = Error;
928
929    fn from_str(text: &str) -> Result<Json> {
930        let mut lex = Lex::new(0, 1, 1);
931        parse_value(text, &mut lex)
932    }
933}
934
935impl AsRef<str> for Json {
936    fn as_ref(&self) -> &str {
937        match self {
938            Json::String(s) => s,
939            _ => panic!("Json is not string"),
940        }
941    }
942}
943
944impl AsRef<Vec<Json>> for Json {
945    fn as_ref(&self) -> &Vec<Json> {
946        match self {
947            Json::Array(arr) => arr,
948            _ => panic!("Json is not an array"),
949        }
950    }
951}
952
953impl AsRef<Vec<Property>> for Json {
954    fn as_ref(&self) -> &Vec<Property> {
955        match self {
956            Json::Object(obj) => obj,
957            _ => panic!("Json is not an object"),
958        }
959    }
960}
961
962impl AsMut<str> for Json {
963    fn as_mut(&mut self) -> &mut str {
964        match self {
965            Json::String(s) => s,
966            _ => panic!("Json is not string"),
967        }
968    }
969}
970
971impl AsMut<Vec<Json>> for Json {
972    fn as_mut(&mut self) -> &mut Vec<Json> {
973        match self {
974            Json::Array(arr) => arr,
975            _ => panic!("Json is not an array"),
976        }
977    }
978}
979
980impl AsMut<Vec<Property>> for Json {
981    fn as_mut(&mut self) -> &mut Vec<Property> {
982        match self {
983            Json::Object(obj) => obj,
984            _ => panic!("Json is not an object"),
985        }
986    }
987}
988
989impl Display for Json {
990    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
991        use self::Json::{Array, Bool, Float, Integer, Null, Object, String as S};
992        use std::str::from_utf8;
993
994        match self {
995            Null => write!(f, "null"),
996            Bool(true) => write!(f, "true"),
997            Bool(false) => write!(f, "false"),
998            Integer(Integral::Text { len, bytes }) => {
999                let arg = from_utf8(&bytes[..*len]).unwrap();
1000                write!(f, "{}", arg)
1001            }
1002            Integer(Integral::Data { value: v }) => write!(f, "{}", v),
1003            Float(Floating::Text { len, bytes }) => {
1004                let arg = from_utf8(&bytes[..*len]).unwrap();
1005                write!(f, "{}", arg)
1006            }
1007            Float(Floating::Data { value: v }) => write!(f, "{:e}", v),
1008            S(val) => {
1009                encode_string(f, val)?;
1010                Ok(())
1011            }
1012            Array(val) => {
1013                if val.is_empty() {
1014                    write!(f, "[]")
1015                } else {
1016                    write!(f, "[")?;
1017                    for item in val[..val.len() - 1].iter() {
1018                        write!(f, "{},", item)?;
1019                    }
1020                    write!(f, "{}", val[val.len() - 1])?;
1021                    write!(f, "]")
1022                }
1023            }
1024            Object(val) => {
1025                let val_len = val.len();
1026                if val_len == 0 {
1027                    write!(f, "{{}}")
1028                } else {
1029                    write!(f, "{{")?;
1030                    for (i, prop) in val.iter().enumerate() {
1031                        encode_string(f, prop.as_key())?;
1032                        write!(f, ":{}", prop.as_value())?;
1033                        if i < (val_len - 1) {
1034                            write!(f, ",")?;
1035                        }
1036                    }
1037                    write!(f, "}}")
1038                }
1039            }
1040            Json::__Error(err) => write!(f, "error: {:?}", err),
1041            Json::__Minbound => write!(f, "minbound"),
1042            Json::__Maxbound => write!(f, "maxbound"),
1043        }
1044    }
1045}
1046
1047fn encode_string<W: Write>(w: &mut W, val: &str) -> fmt::Result {
1048    write!(w, "\"")?;
1049
1050    let mut start = 0;
1051    for (i, byte) in val.bytes().enumerate() {
1052        let escstr = ESCAPE[usize::from(byte)];
1053        if escstr.is_empty() {
1054            continue;
1055        }
1056
1057        if start < i {
1058            write!(w, "{}", &val[start..i])?;
1059        }
1060        write!(w, "{}", escstr)?;
1061        start = i + 1;
1062    }
1063    if start != val.len() {
1064        write!(w, "{}", &val[start..])?;
1065    }
1066    write!(w, "\"")
1067}
1068
1069pub fn insert(json: &mut Json, item: Property) {
1070    let item_key = item.as_key();
1071    if let Json::Object(obj) = json {
1072        match obj.binary_search_by(|p| p.as_key().cmp(item_key)) {
1073            Ok(off) => {
1074                obj.push(item);
1075                obj.swap_remove(off);
1076            }
1077            Err(off) => obj.insert(off, item),
1078        }
1079    }
1080}
1081
1082static ESCAPE: [&str; 256] = [
1083    "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006",
1084    "\\u0007", "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f",
1085    "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016",
1086    "\\u0017", "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d",
1087    "\\u001e", "\\u001f", "", "", "\\\"", "", "", "", "", "", "", "", "", "", "", "", "",
1088    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1089    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1090    "", "", "", "\\\\", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1091    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u007f",
1092    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1093    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1094    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1095    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1096    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1097    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1098    "", "",
1099];
1100
1101#[cfg(test)]
1102#[path = "json_test.rs"]
1103mod json_test;