json_spanned_value/
value.rs

1use crate::*;
2
3use serde::de;
4
5use std::convert::*;
6use std::fmt::{self, Debug, Formatter};
7
8
9
10/// A basic un-[Spanned] value, with [Spanned] children.
11/// Unless you want to `match` it, you probably want [spanned::Value].
12pub enum Value {
13    #[doc="`null`"                                 ] Null,
14    #[doc="`true` or `false`"                      ] Bool(bool),
15    #[doc="A number like `123`"                    ] Number(serde_json::Number),
16    #[doc="A string like `\"asdf\"`"               ] String(String),
17    #[doc="An array like `[1, 2, 3]`"              ] Array(Vec<Spanned<Value>>),
18    #[doc="An object like `{\"a\": 1, \"b\": 2}`"  ] Object(Map<Spanned<String>, Spanned<Value>>),
19}
20
21impl Value {
22    #[doc="True if self is `null`"                                          ] pub fn is_null    (&self) -> bool { match self { Value::Null      => true, _ => false } }
23    #[doc="True if self is `true` or `false`"                               ] pub fn is_bool    (&self) -> bool { match self { Value::Bool(_)   => true, _ => false } }
24    #[doc="True if self is a number like `123`"                             ] pub fn is_number  (&self) -> bool { match self { Value::Number(_) => true, _ => false } }
25    #[doc="True if self is a string like `\"asdf\"`"                        ] pub fn is_string  (&self) -> bool { match self { Value::String(_) => true, _ => false } }
26    #[doc="True if self is an array like `[1, 2, 3]`"                       ] pub fn is_array   (&self) -> bool { match self { Value::Array(_)  => true, _ => false } }
27    #[doc="True if self is an object like `{\"a\": 1, \"b\": 2}`"           ] pub fn is_object  (&self) -> bool { match self { Value::Object(_) => true, _ => false } }
28 
29    #[doc="`Some(()) if self is `null`"                                     ] pub fn as_null      (&self) -> Option<()>                                       { match self { Value::Null      => Some(()), _ => None } }
30    #[doc="`Some(inner)` if self is `true` or `false`"                      ] pub fn as_bool      (&self) -> Option<bool>                                     { match self { Value::Bool(v)   => Some(*v), _ => None } }
31    #[doc="`Some(&inner)` if self is a number like `123`"                   ] pub fn as_number    (&self) -> Option<&serde_json::Number>                      { match self { Value::Number(v) => Some(v), _ => None } }
32    #[doc="`Some(&inner)` if self is a string like `\"asdf\"`"              ] pub fn as_string    (&self) -> Option<&str>                                     { match self { Value::String(v) => Some(v), _ => None } }
33    #[doc="`Some(&inner)` if self is an array like `[1, 2, 3]`"             ] pub fn as_array     (&self) -> Option<&Vec<Spanned<Value>>>                     { match self { Value::Array(v)  => Some(v), _ => None } }
34    #[doc="`Some(&inner)` if self is an object like `{\"a\": 1, \"b\": 2}`" ] pub fn as_object    (&self) -> Option<&Map<Spanned<String>, Spanned<Value>>>    { match self { Value::Object(v) => Some(v), _ => None } }
35
36    // no as_null_mut
37    #[doc="`Some(&mut v)` if self is `true` or `false`"                     ] pub fn as_bool_mut  (&mut self) -> Option<&mut bool>                                    { match self { Value::Bool(v) => Some(v), _ => None } }
38    #[doc="`Some(&mut v)` if self is a number like `123`"                   ] pub fn as_number_mut(&mut self) -> Option<&mut serde_json::Number>                      { match self { Value::Number(v) => Some(v), _ => None } }
39    #[doc="`Some(&mut v)` if self is a string like `\"asdf\"`"              ] pub fn as_string_mut(&mut self) -> Option<&mut String>                                  { match self { Value::String(v) => Some(v), _ => None } }
40    #[doc="`Some(&mut v)` if self is an array like `[1, 2, 3]`"             ] pub fn as_array_mut (&mut self) -> Option<&mut Vec<Spanned<Value>>>                     { match self { Value::Array(v) => Some(v), _ => None } }
41    #[doc="`Some(&mut v)` if self is an object like `{\"a\": 1, \"b\": 2}`" ] pub fn as_object_mut(&mut self) -> Option<&mut Map<Spanned<String>, Spanned<Value>>>    { match self { Value::Object(v) => Some(v), _ => None } }
42
43    #[doc="`Ok(inner)` if self is `null`, otherwise `Err(self)`"                                ] pub fn into_null    (self) -> Result<(), Self>                                      { match self { Value::Null      => Ok(()), o => Err(o) } }
44    #[doc="`Ok(inner)` if self is `true` or `false`, otherwise `Err(self)`"                     ] pub fn into_bool    (self) -> Result<bool, Self>                                    { match self { Value::Bool(v)   => Ok(v), o => Err(o) } }
45    #[doc="`Ok(inner)` if self is a number like `123`, otherwise `Err(self)`"                   ] pub fn into_number  (self) -> Result<serde_json::Number, Self>                      { match self { Value::Number(v) => Ok(v), o => Err(o) } }
46    #[doc="`Ok(inner)` if self is a string like `\"asdf\"`, otherwise `Err(self)`"              ] pub fn into_string  (self) -> Result<String, Self>                                  { match self { Value::String(v) => Ok(v), o => Err(o) } }
47    #[doc="`Ok(inner)` if self is an array like `[1, 2, 3]`, otherwise `Err(self)`"             ] pub fn into_array   (self) -> Result<Vec<Spanned<Value>>, Self>                     { match self { Value::Array(v)  => Ok(v), o => Err(o) } }
48    #[doc="`Ok(inner)` if self is an object like `{\"a\": 1, \"b\": 2}`, otherwise `Err(self)`" ] pub fn into_object  (self) -> Result<Map<Spanned<String>, Spanned<Value>>, Self>    { match self { Value::Object(v) => Ok(v), o => Err(o) } }
49
50    /// A human-readable representation of the type of this value
51    pub fn type_str(&self) -> &'static str {
52        match self {
53            Value::Null         => "null",
54            Value::Bool(_)      => "boolean",
55            Value::Number(_)    => "number",
56            Value::String(_)    => "string",
57            Value::Array(_)     => "array",
58            Value::Object(_)    => "object",
59        }
60    }
61}
62
63impl Debug for Value {
64    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
65        match self {
66            Value::Null         => write!(fmt, "null"),
67            Value::Bool(true)   => write!(fmt, "true"),
68            Value::Bool(false)  => write!(fmt, "false"),
69            Value::Number(n)    => write!(fmt, "{}", n),
70            Value::String(s)    => write!(fmt, "{:?}", s),
71            Value::Array(a) => {
72                write!(fmt, "[")?;
73                if a.len() > 32 {
74                    write!(fmt, "...")?;
75                } else {
76                    let mut first = true;
77                    for e in a.iter() {
78                        write!(fmt, "{}", if first { " " } else { ", " })?;
79                        write!(fmt, "{:?}", e)?;
80                        first = false;
81                    }
82                    if !first { write!(fmt, " ")?; }
83                }
84                write!(fmt, "]")
85            },
86            Value::Object(o) => {
87                write!(fmt, "{{")?;
88                if o.len() > 32 {
89                    write!(fmt, "...")?;
90                } else {
91                    let mut first = true;
92                    for (k, v) in o.iter() {
93                        write!(fmt, "{}", if first { " " } else { ", " })?;
94                        write!(fmt, "{:?}: {:?}", k, v)?;
95                        first = false;
96                    }
97                    if !first { write!(fmt, " ")?; }
98                }
99                write!(fmt, "}}")
100            },
101        }
102    }
103}
104
105impl<'de> de::Deserialize<'de> for Value {
106    fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
107        struct ValueVisitor;
108        impl<'de> de::Visitor<'de> for ValueVisitor {
109            type Value = Value;
110            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { formatter.write_str("any valid JSON value") }
111
112            fn visit_bool   <E>(self, value: bool)      -> Result<Value, E> { Ok(Value::Bool(value)) }
113            fn visit_i64    <E>(self, value: i64)       -> Result<Value, E> { Ok(Value::Number(value.into())) }
114            fn visit_u64    <E>(self, value: u64)       -> Result<Value, E> { Ok(Value::Number(value.into())) }
115            fn visit_f64    <E>(self, value: f64)       -> Result<Value, E> { Ok(serde_json::Number::from_f64(value).map_or(Value::Null, Value::Number)) }
116            fn visit_str    <E>(self, value: &str)      -> Result<Value, E> { Ok(Value::String(String::from(value))) }
117            fn visit_string <E>(self, value: String)    -> Result<Value, E> { Ok(Value::String(value)) }
118            fn visit_none   <E>(self)                   -> Result<Value, E> { Ok(Value::Null) }
119            fn visit_unit   <E>(self)                   -> Result<Value, E> { Ok(Value::Null) }
120
121            fn visit_some<D: de::Deserializer<'de>>(self, deserializer: D) -> Result<Value, D::Error> { de::Deserialize::deserialize(deserializer) }
122
123            fn visit_seq<V: de::SeqAccess<'de>>(self, mut visitor: V) -> Result<Value, V::Error> {
124                let mut vec = Vec::new();
125                while let Some(elem) = visitor.next_element()? { vec.push(elem); }
126                Ok(Value::Array(vec))
127            }
128
129            fn visit_map<V: de::MapAccess<'de>>(self, mut visitor: V) -> Result<Value, V::Error> {
130                let mut values = Map::new();
131                while let Some(key) = visitor.next_key()? {
132                    if !settings().map_or(false, |s| s.allow_duplicate_keys) && values.contains_key(&key) {
133                        return Err(de::Error::custom(format!("Duplicate field: {:?}", key)));
134                    }
135                    let value = visitor.next_value()?;
136                    values.insert(key, value);
137                }
138                Ok(Value::Object(values))
139            }
140        }
141
142        deserializer.deserialize_any(ValueVisitor)
143    }
144}