yojson_rs/
value.rs

1//! Definition of a Yojson value
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::mem::discriminant;
6
7/// Representation of a Yojson value.
8#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
9pub enum Value {
10  /// JSON null
11  Null,
12  /// JSON boolean
13  Bool(bool),
14  /// JSON number without decimal point or exponent.
15  Integer(i64),
16  /// JSON number, Infinity, -Infinity or NaN.
17  Float(f64),
18  /// JSON string.
19  String(String),
20  /// JSON object.
21  Assoc(Assoc),
22  /// JSON array
23  Array(Array),
24  /// Tuple (non-standard extension of JSON). Syntax: `("abc", 123)`.
25  Tuple(Vec<Value>),
26  /// Variant (non-standard extension of JSON). Syntax: `<"Foo">` or `<"Bar":123>`.
27  Variant(Variant),
28}
29
30/// JSON object.
31pub type Assoc = HashMap<String, Value>;
32
33/// JSON array
34pub type Array = Vec<Value>;
35
36/// Variant (non-standard extension of JSON). Syntax: `<"Foo">` or `<"Bar":123>`.
37pub type Variant = (String, Option<Box<Value>>);
38
39impl Value {
40  /// Tests whether this value is a null.
41  pub fn is_null(&self) -> bool {
42    matches!(self, Value::Null)
43  }
44
45  /// Extracts the integer value if it is an integer.
46  pub fn as_integer(&self) -> Option<i64> {
47    match *self {
48      Value::Integer(i) => Some(i),
49      _ => None,
50    }
51  }
52
53  /// Tests whether this value is an integer.
54  pub fn is_integer(&self) -> bool {
55    self.as_integer().is_some()
56  }
57
58  /// Extracts the float value if it is a float.
59  pub fn as_float(&self) -> Option<f64> {
60    match *self {
61      Value::Float(f) => Some(f),
62      _ => None,
63    }
64  }
65
66  /// Tests whether this value is a float.
67  pub fn is_float(&self) -> bool {
68    self.as_float().is_some()
69  }
70
71  /// Extracts the boolean value if it is a boolean.
72  pub fn as_bool(&self) -> Option<bool> {
73    match *self {
74      Value::Bool(b) => Some(b),
75      _ => None,
76    }
77  }
78
79  /// Tests whether this value is a boolean.
80  pub fn is_bool(&self) -> bool {
81    self.as_bool().is_some()
82  }
83
84  /// Extracts the string of this value if it is a string.
85  pub fn as_str(&self) -> Option<&str> {
86    match *self {
87      Value::String(ref s) => Some(&**s),
88      _ => None,
89    }
90  }
91
92  /// Tests if this value is a string.
93  pub fn is_str(&self) -> bool {
94    self.as_str().is_some()
95  }
96
97  /// Extracts the array value if it is an array.
98  pub fn as_array(&self) -> Option<&Vec<Value>> {
99    match *self {
100      Value::Array(ref s) => Some(s),
101      _ => None,
102    }
103  }
104
105  /// Extracts the array value if it is an array.
106  pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
107    match *self {
108      Value::Array(ref mut s) => Some(s),
109      _ => None,
110    }
111  }
112
113  /// Tests whether this value is an array.
114  pub fn is_array(&self) -> bool {
115    self.as_array().is_some()
116  }
117
118  /// Extracts the list values if it is a tuple.
119  pub fn as_tuple(&self) -> Option<&Vec<Value>> {
120    match *self {
121      Value::Tuple(ref s) => Some(s),
122      _ => None,
123    }
124  }
125
126  /// Extracts the list values if it is a tuple.
127  pub fn as_tuple_mut(&mut self) -> Option<&mut Vec<Value>> {
128    match *self {
129      Value::Tuple(ref mut s) => Some(s),
130      _ => None,
131    }
132  }
133
134  /// Tests whether this value is a tuple.
135  pub fn is_tuple(&self) -> bool {
136    self.as_tuple().is_some()
137  }
138
139  /// Extracts the objects value if it is an assoc.
140  pub fn as_assoc(&self) -> Option<&HashMap<String, Value>> {
141    match *self {
142      Value::Assoc(ref s) => Some(s),
143      _ => None,
144    }
145  }
146
147  /// Extracts the objects value if it is an assoc.
148  pub fn as_assoc_mut(&mut self) -> Option<&mut HashMap<String, Value>> {
149    match *self {
150      Value::Assoc(ref mut s) => Some(s),
151      _ => None,
152    }
153  }
154
155  /// Tests whether this value is an assoc.
156  pub fn is_assoc(&self) -> bool {
157    self.as_assoc().is_some()
158  }
159
160  /// Extracts the variant value if it is a variant.
161  pub fn as_variant(&self) -> Option<&Variant> {
162    match *self {
163      Value::Variant(ref s) => Some(s),
164      _ => None,
165    }
166  }
167
168  /// Extracts the variant value if it is a variant.
169  pub fn as_variant_mut(&mut self) -> Option<&mut Variant> {
170    match *self {
171      Value::Variant(ref mut s) => Some(s),
172      _ => None,
173    }
174  }
175
176  /// Tests whether this value is a variant.
177  pub fn is_variant(&self) -> bool {
178    self.as_variant().is_some()
179  }
180
181  /// Tests whether this and another value have the same type.
182  pub fn same_type(&self, other: &Value) -> bool {
183    discriminant(self) == discriminant(other)
184  }
185
186  /// Returns a human-readable representation of the type of this value.
187  pub fn type_str(&self) -> &'static str {
188    match *self {
189      Value::Null => "null",
190      Value::String(..) => "string",
191      Value::Integer(..) => "integer",
192      Value::Float(..) => "float",
193      Value::Bool(..) => "boolean",
194      Value::Array(..) => "array",
195      Value::Assoc(..) => "assoc",
196      Value::Tuple(..) => "tuple",
197      Value::Variant(..) => "variant",
198    }
199  }
200}