json\value/
mod.rs

1use std::ops::{Index, IndexMut, Deref};
2use std::convert::TryInto;
3use std::{fmt, mem, usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32};
4use std::io::{self, Write};
5
6use crate::{Result, Error};
7use crate::short::Short;
8use crate::number::Number;
9use crate::object::Object;
10use crate::iterators::{ Members, MembersMut, Entries, EntriesMut };
11use crate::codegen::{ Generator, PrettyGenerator, DumpGenerator, WriterGenerator, PrettyWriterGenerator };
12
13mod implements;
14
15// These are convenience macros for converting `f64` to the `$unsigned` type.
16// The macros check that the numbers are representable the target type.
17macro_rules! number_to_unsigned {
18    ($unsigned:ident, $value:expr, $high:ty) => {
19        if $value > $unsigned::MAX as $high {
20            None
21        } else {
22            Some($value as $unsigned)
23        }
24    }
25}
26
27macro_rules! number_to_signed {
28    ($signed:ident, $value:expr, $high:ty) => {
29        if $value < $signed::MIN as $high || $value > $signed::MAX as $high {
30            None
31        } else {
32            Some($value as $signed)
33        }
34    }
35}
36
37#[derive(Debug, Clone)]
38pub enum JsonValue {
39    Null,
40    Short(Short),
41    String(String),
42    Number(Number),
43    Boolean(bool),
44    Object(Object),
45    Array(Vec<JsonValue>),
46}
47
48impl PartialEq for JsonValue {
49    fn eq(&self, other: &Self) -> bool {
50        use self::JsonValue::*;
51        match (self, other) {
52            (&Null, &Null) => true,
53            (&Short(ref a), &Short(ref b)) => a == b,
54            (&String(ref a), &String(ref b)) => a == b,
55            (&Short(ref a), &String(ref b))
56            | (&String(ref b), &Short(ref a)) => a.as_str() == b.as_str(),
57            (&Number(ref a), &Number(ref b)) => a == b,
58            (&Boolean(ref a), &Boolean(ref b)) => a == b,
59            (&Object(ref a), &Object(ref b)) => a == b,
60            (&Array(ref a), &Array(ref b)) => a == b,
61            _ => false,
62        }
63    }
64}
65
66impl Eq for JsonValue {}
67
68/// Implements formatting
69///
70/// ```
71/// # use json;
72/// let data = json::parse(r#"{"url":"https://github.com/"}"#).unwrap();
73/// println!("{}", data);
74/// println!("{:#}", data);
75/// ```
76impl fmt::Display for JsonValue {
77    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78        if f.alternate() {
79            f.write_str(&self.pretty(4))
80        } else {
81            match *self {
82                JsonValue::Short(ref value)   => value.fmt(f),
83                JsonValue::String(ref value)  => value.fmt(f),
84                JsonValue::Number(ref value)  => value.fmt(f),
85                JsonValue::Boolean(ref value) => value.fmt(f),
86                JsonValue::Null               => f.write_str("null"),
87                _                             => f.write_str(&self.dump())
88            }
89        }
90    }
91}
92
93
94static NULL: JsonValue = JsonValue::Null;
95
96impl JsonValue {
97    /// Create an empty `JsonValue::Object` instance.
98    /// When creating an object with data, consider using the `object!` macro.
99    pub fn new_object() -> JsonValue {
100        JsonValue::Object(Object::new())
101    }
102
103    /// Create an empty `JsonValue::Array` instance.
104    /// When creating array with data, consider using the `array!` macro.
105    pub fn new_array() -> JsonValue {
106        JsonValue::Array(Vec::new())
107    }
108
109    /// Prints out the value as JSON string.
110    pub fn dump(&self) -> String {
111        let mut gen = DumpGenerator::new();
112        gen.write_json(self).expect("Can't fail");
113        gen.consume()
114    }
115
116    /// Pretty prints out the value as JSON string. Takes an argument that's
117    /// number of spaces to indent new blocks with.
118    pub fn pretty(&self, spaces: u16) -> String {
119        let mut gen = PrettyGenerator::new(spaces);
120        gen.write_json(self).expect("Can't fail");
121        gen.consume()
122    }
123
124    /// Writes the JSON as byte stream into an implementor of `std::io::Write`.
125    ///
126    /// This method is deprecated as it will panic on io errors, use `write` instead.
127    #[deprecated(since="0.10.2", note="use `JsonValue::write` instead")]
128    pub fn to_writer<W: Write>(&self, writer: &mut W) {
129        let mut gen = WriterGenerator::new(writer);
130        gen.write_json(self).expect("Deprecated");
131    }
132
133    /// Writes the JSON as byte stream into an implementor of `std::io::Write`.
134    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
135        let mut gen = WriterGenerator::new(writer);
136        gen.write_json(self)
137    }
138
139    /// Writes the JSON as byte stream into an implementor of `std::io::Write`.
140    pub fn write_pretty<W: Write>(&self, writer: &mut W, spaces: u16) -> io::Result<()> {
141        let mut gen = PrettyWriterGenerator::new(writer, spaces);
142        gen.write_json(self)
143    }
144
145    pub fn is_string(&self) -> bool {
146        match *self {
147            JsonValue::Short(_)  => true,
148            JsonValue::String(_) => true,
149            _                    => false,
150        }
151    }
152
153    pub fn is_number(&self) -> bool {
154        match *self {
155            JsonValue::Number(_) => true,
156            _                    => false,
157        }
158    }
159
160    pub fn is_boolean(&self) -> bool {
161        match *self {
162            JsonValue::Boolean(_) => true,
163            _                     => false
164        }
165    }
166
167    pub fn is_null(&self) -> bool {
168        match *self {
169            JsonValue::Null => true,
170            _               => false,
171        }
172    }
173
174    pub fn is_object(&self) -> bool {
175        match *self {
176            JsonValue::Object(_) => true,
177            _                    => false,
178        }
179    }
180
181    pub fn is_array(&self) -> bool {
182        match *self {
183            JsonValue::Array(_) => true,
184            _                   => false,
185        }
186    }
187
188    /// Checks whether the value is empty. Returns true for:
189    ///
190    /// - empty string (`""`)
191    /// - number `0`
192    /// - boolean `false`
193    /// - null
194    /// - empty array (`array![]`)
195    /// - empty object (`object!{}`)
196    pub fn is_empty(&self) -> bool {
197        match *self {
198            JsonValue::Null               => true,
199            JsonValue::Short(ref value)   => value.is_empty(),
200            JsonValue::String(ref value)  => value.is_empty(),
201            JsonValue::Number(ref value)  => value.is_empty(),
202            JsonValue::Boolean(ref value) => !value,
203            JsonValue::Array(ref value)   => value.is_empty(),
204            JsonValue::Object(ref value)  => value.is_empty(),
205        }
206    }
207
208    pub fn as_str(&self) -> Option<&str> {
209        match *self {
210            JsonValue::Short(ref value)  => Some(value),
211            JsonValue::String(ref value) => Some(value),
212            _                            => None
213        }
214    }
215
216    pub fn as_number(&self) -> Option<Number> {
217        match *self {
218            JsonValue::Number(value) => Some(value),
219            _                        => None
220        }
221    }
222
223    pub fn as_f64(&self) -> Option<f64> {
224        self.as_number().map(|value| value.into())
225    }
226
227    pub fn as_f32(&self) -> Option<f32> {
228        self.as_number().map(|value| value.into())
229    }
230
231    pub fn as_u64(&self) -> Option<u64> {
232        self.as_number().and_then(|value| {
233            value.try_into().ok()
234        })
235    }
236
237    pub fn as_u32(&self) -> Option<u32> {
238        self.as_u64().and_then(|value| number_to_unsigned!(u32, value, u64))
239    }
240
241    pub fn as_u16(&self) -> Option<u16> {
242        self.as_u64().and_then(|value| number_to_unsigned!(u16, value, u64))
243    }
244
245    pub fn as_u8(&self) -> Option<u8> {
246        self.as_u64().and_then(|value| number_to_unsigned!(u8, value, u64))
247    }
248
249    pub fn as_usize(&self) -> Option<usize> {
250        self.as_u64().and_then(|value| number_to_unsigned!(usize, value, u64))
251    }
252
253    pub fn as_i64(&self) -> Option<i64> {
254        self.as_number().and_then(|value| value.try_into().ok())
255    }
256
257    pub fn as_i32(&self) -> Option<i32> {
258        self.as_i64().and_then(|value| number_to_signed!(i32, value, i64))
259    }
260
261    pub fn as_i16(&self) -> Option<i16> {
262        self.as_i64().and_then(|value| number_to_signed!(i16, value, i64))
263    }
264
265    pub fn as_i8(&self) -> Option<i8> {
266        self.as_i64().and_then(|value| number_to_signed!(i8, value, i64))
267    }
268
269    pub fn as_isize(&self) -> Option<isize> {
270        self.as_i64().and_then(|value| number_to_signed!(isize, value, i64))
271    }
272
273    pub fn as_bool(&self) -> Option<bool> {
274        match *self {
275            JsonValue::Boolean(ref value) => Some(*value),
276            _                             => None
277        }
278    }
279
280    /// Obtain an integer at a fixed decimal point. This is useful for
281    /// converting monetary values and doing arithmetic on them without
282    /// rounding errors introduced by floating point operations.
283    ///
284    /// Will return `None` if `Number` called on a value that's not a number,
285    /// or if the number is negative or a NaN.
286    ///
287    /// ```
288    /// # use json::JsonValue;
289    /// let price_a = JsonValue::from(5.99);
290    /// let price_b = JsonValue::from(7);
291    /// let price_c = JsonValue::from(10.2);
292    ///
293    /// assert_eq!(price_a.as_fixed_point_u64(2), Some(599));
294    /// assert_eq!(price_b.as_fixed_point_u64(2), Some(700));
295    /// assert_eq!(price_c.as_fixed_point_u64(2), Some(1020));
296    /// ```
297    pub fn as_fixed_point_u64(&self, point: u16) -> Option<u64> {
298        match *self {
299            JsonValue::Number(ref value) => value.as_fixed_point_u64(point),
300            _                            => None
301        }
302    }
303
304    /// Analog to `as_fixed_point_u64`, except returning a signed
305    /// `i64`, properly handling negative numbers.
306    ///
307    /// ```
308    /// # use json::JsonValue;
309    /// let balance_a = JsonValue::from(-1.49);
310    /// let balance_b = JsonValue::from(42);
311    ///
312    /// assert_eq!(balance_a.as_fixed_point_i64(2), Some(-149));
313    /// assert_eq!(balance_b.as_fixed_point_i64(2), Some(4200));
314    /// ```
315    pub fn as_fixed_point_i64(&self, point: u16) -> Option<i64> {
316        match *self {
317            JsonValue::Number(ref value) => value.as_fixed_point_i64(point),
318            _                            => None
319        }
320    }
321
322    /// Take over the ownership of the value, leaving `Null` in it's place.
323    ///
324    /// ## Example
325    ///
326    /// ```
327    /// # #[macro_use] extern crate json;
328    /// # fn main() {
329    /// let mut data = array!["Foo", 42];
330    ///
331    /// let first = data[0].take();
332    /// let second = data[1].take();
333    ///
334    /// assert!(first == "Foo");
335    /// assert!(second == 42);
336    ///
337    /// assert!(data[0].is_null());
338    /// assert!(data[1].is_null());
339    /// # }
340    /// ```
341    pub fn take(&mut self) -> JsonValue {
342        mem::replace(self, JsonValue::Null)
343    }
344
345    /// Checks that self is a string, returns an owned Rust `String`, leaving
346    /// `Null` in it's place.
347    ///
348    /// - If the contained string is already a heap allocated `String`, then
349    /// the ownership is moved without any heap allocation.
350    ///
351    /// - If the contained string is a `Short`, this will perform a heap
352    /// allocation to convert the types for you.
353    ///
354    /// ## Example
355    ///
356    /// ```
357    /// # #[macro_use] extern crate json;
358    /// # fn main() {
359    /// let mut data = array!["Hello", "World"];
360    ///
361    /// let owned = data[0].take_string().expect("Should be a string");
362    ///
363    /// assert_eq!(owned, "Hello");
364    /// assert!(data[0].is_null());
365    /// # }
366    /// ```
367    pub fn take_string(&mut self) -> Option<String> {
368        let mut placeholder = JsonValue::Null;
369
370        mem::swap(self, &mut placeholder);
371
372        match placeholder {
373            JsonValue::Short(short)   => return Some(short.into()),
374            JsonValue::String(string) => return Some(string),
375
376            // Not a string? Swap the original value back in place!
377            _ => mem::swap(self, &mut placeholder)
378        }
379
380        None
381    }
382
383    /// Works on `JsonValue::Array` - pushes a new value to the array.
384    pub fn push<T>(&mut self, value: T) -> Result<()>
385    where T: Into<JsonValue> {
386        match *self {
387            JsonValue::Array(ref mut vec) => {
388                vec.push(value.into());
389                Ok(())
390            },
391            _ => Err(Error::wrong_type("Array"))
392        }
393    }
394
395    /// Works on `JsonValue::Array` - remove and return last element from
396    /// an array. On failure returns a null.
397    pub fn pop(&mut self) -> JsonValue {
398        match *self {
399            JsonValue::Array(ref mut vec) => {
400                vec.pop().unwrap_or(JsonValue::Null)
401            },
402            _ => JsonValue::Null
403        }
404    }
405
406    /// Works on `JsonValue::Array` - checks if the array contains a value
407    pub fn contains<T>(&self, item: T) -> bool where T: PartialEq<JsonValue> {
408        match *self {
409            JsonValue::Array(ref vec) => vec.iter().any(|member| item == *member),
410            _                         => false
411        }
412    }
413
414    /// Works on `JsonValue::Object` - checks if the object has a key
415    pub fn has_key(&self, key: &str) -> bool {
416        match *self {
417            JsonValue::Object(ref object) => object.get(key).is_some(),
418            _                             => false
419        }
420    }
421
422    /// Returns length of array or object (number of keys), defaults to `0` for
423    /// other types.
424    pub fn len(&self) -> usize {
425        match *self {
426            JsonValue::Array(ref vec) => {
427                vec.len()
428            },
429            JsonValue::Object(ref object) => {
430                object.len()
431            },
432            _ => 0
433        }
434    }
435
436    /// Works on `JsonValue::Array` - returns an iterator over members.
437    /// Will return an empty iterator if called on non-array types.
438    pub fn members(&self) -> Members {
439        match *self {
440            JsonValue::Array(ref vec) => {
441                vec.iter()
442            },
443            _ => [].iter()
444        }
445    }
446
447    /// Works on `JsonValue::Array` - returns a mutable iterator over members.
448    /// Will return an empty iterator if called on non-array types.
449    pub fn members_mut(&mut self) -> MembersMut {
450        match *self {
451            JsonValue::Array(ref mut vec) => {
452                vec.iter_mut()
453            },
454            _ => [].iter_mut()
455        }
456    }
457
458    /// Works on `JsonValue::Object` - returns an iterator over key value pairs.
459    /// Will return an empty iterator if called on non-object types.
460    pub fn entries(&self) -> Entries {
461        match *self {
462            JsonValue::Object(ref object) => {
463                object.iter()
464            },
465            _ => Entries::empty()
466        }
467    }
468
469    /// Works on `JsonValue::Object` - returns a mutable iterator over
470    /// key value pairs.
471    /// Will return an empty iterator if called on non-object types.
472    pub fn entries_mut(&mut self) -> EntriesMut {
473        match *self {
474            JsonValue::Object(ref mut object) => {
475                object.iter_mut()
476            },
477            _ => EntriesMut::empty()
478        }
479    }
480
481    /// Works on `JsonValue::Object` - inserts a new entry, or override an existing
482    /// one into the object. Note that `key` has to be a `&str` slice and not an owned
483    /// `String`. The internals of `Object` will handle the heap allocation of the key
484    /// if needed for better performance.
485    pub fn insert<T>(&mut self, key: &str, value: T) -> Result<()>
486    where T: Into<JsonValue> {
487        match *self {
488            JsonValue::Object(ref mut object) => {
489                object.insert(key, value.into());
490                Ok(())
491            },
492            _ => Err(Error::wrong_type("Object"))
493        }
494    }
495
496    /// Works on `JsonValue::Object` - remove a key and return the value it held.
497    /// If the key was not present, the method is called on anything but an
498    /// object, it will return a null.
499    pub fn remove(&mut self, key: &str) -> JsonValue {
500        match *self {
501            JsonValue::Object(ref mut object) => {
502                object.remove(key).unwrap_or(JsonValue::Null)
503            },
504            _ => JsonValue::Null
505        }
506    }
507
508    /// Works on `JsonValue::Array` - remove an entry and return the value it held.
509    /// If the method is called on anything but an object or if the index is out of bounds, it
510    /// will return `JsonValue::Null`.
511    pub fn array_remove(&mut self, index: usize) -> JsonValue {
512        match *self {
513            JsonValue::Array(ref mut vec) => {
514                if index < vec.len() {
515                    vec.remove(index)
516                } else {
517                    JsonValue::Null
518                }
519            },
520            _ => JsonValue::Null
521        }
522    }
523
524    /// When called on an array or an object, will wipe them clean. When called
525    /// on a string will clear the string. Numbers and booleans become null.
526    pub fn clear(&mut self) {
527        match *self {
528            JsonValue::String(ref mut string) => string.clear(),
529            JsonValue::Object(ref mut object) => object.clear(),
530            JsonValue::Array(ref mut vec)     => vec.clear(),
531            _                                 => *self = JsonValue::Null,
532        }
533    }
534}
535
536/// Implements indexing by `usize` to easily access array members:
537///
538/// ## Example
539///
540/// ```
541/// # use json::JsonValue;
542/// let mut array = JsonValue::new_array();
543///
544/// array.push("foo");
545///
546/// assert!(array[0] == "foo");
547/// ```
548impl Index<usize> for JsonValue {
549    type Output = JsonValue;
550
551    fn index(&self, index: usize) -> &JsonValue {
552        match *self {
553            JsonValue::Array(ref vec) => vec.get(index).unwrap_or(&NULL),
554            _ => &NULL
555        }
556    }
557}
558
559/// Implements mutable indexing by `usize` to easily modify array members:
560///
561/// ## Example
562///
563/// ```
564/// # #[macro_use]
565/// # extern crate json;
566/// #
567/// # fn main() {
568/// let mut array = array!["foo", 3.14];
569///
570/// array[1] = "bar".into();
571///
572/// assert!(array[1] == "bar");
573/// # }
574/// ```
575impl IndexMut<usize> for JsonValue {
576    fn index_mut(&mut self, index: usize) -> &mut JsonValue {
577        match *self {
578            JsonValue::Array(ref mut vec) => {
579                let in_bounds = index < vec.len();
580
581                if in_bounds {
582                    &mut vec[index]
583                } else {
584                    vec.push(JsonValue::Null);
585                    vec.last_mut().unwrap()
586                }
587            }
588            _ => {
589                *self = JsonValue::new_array();
590                self.push(JsonValue::Null).unwrap();
591                self.index_mut(index)
592            }
593        }
594    }
595}
596
597/// Implements indexing by `&str` to easily access object members:
598///
599/// ## Example
600///
601/// ```
602/// # #[macro_use]
603/// # extern crate json;
604/// #
605/// # fn main() {
606/// let object = object!{
607///     foo: "bar"
608/// };
609///
610/// assert!(object["foo"] == "bar");
611/// # }
612/// ```
613impl<'a> Index<&'a str> for JsonValue {
614    type Output = JsonValue;
615
616    fn index(&self, index: &str) -> &JsonValue {
617        match *self {
618            JsonValue::Object(ref object) => &object[index],
619            _ => &NULL
620        }
621    }
622}
623
624impl Index<String> for JsonValue {
625    type Output = JsonValue;
626
627    fn index(&self, index: String) -> &JsonValue {
628        self.index(index.deref())
629    }
630}
631
632impl<'a> Index<&'a String> for JsonValue {
633    type Output = JsonValue;
634
635    fn index(&self, index: &String) -> &JsonValue {
636        self.index(index.deref())
637    }
638}
639
640/// Implements mutable indexing by `&str` to easily modify object members:
641///
642/// ## Example
643///
644/// ```
645/// # #[macro_use]
646/// # extern crate json;
647/// #
648/// # fn main() {
649/// let mut object = object!{};
650///
651/// object["foo"] = 42.into();
652///
653/// assert!(object["foo"] == 42);
654/// # }
655/// ```
656impl<'a> IndexMut<&'a str> for JsonValue {
657    fn index_mut(&mut self, index: &str) -> &mut JsonValue {
658        match *self {
659            JsonValue::Object(ref mut object) => {
660                &mut object[index]
661            },
662            _ => {
663                *self = JsonValue::new_object();
664                self.index_mut(index)
665            }
666        }
667    }
668}
669
670impl IndexMut<String> for JsonValue {
671    fn index_mut(&mut self, index: String) -> &mut JsonValue {
672        self.index_mut(index.deref())
673    }
674}
675
676impl<'a> IndexMut<&'a String> for JsonValue {
677    fn index_mut(&mut self, index: &String) -> &mut JsonValue {
678        self.index_mut(index.deref())
679    }
680}