json_joxit_fork/value/
mod.rs

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