]>
Commit | Line | Data |
---|---|---|
041b39d2 XL |
1 | //! The Value enum, a loosely typed way of representing any valid JSON value. |
2 | //! | |
3 | //! # Constructing JSON | |
4 | //! | |
5 | //! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` | |
416331ca | 6 | //! objects with very natural JSON syntax. |
041b39d2 | 7 | //! |
f035d41b | 8 | //! ``` |
416331ca | 9 | //! use serde_json::json; |
041b39d2 XL |
10 | //! |
11 | //! fn main() { | |
12 | //! // The type of `john` is `serde_json::Value` | |
13 | //! let john = json!({ | |
416331ca XL |
14 | //! "name": "John Doe", |
15 | //! "age": 43, | |
16 | //! "phones": [ | |
17 | //! "+44 1234567", | |
18 | //! "+44 2345678" | |
19 | //! ] | |
041b39d2 XL |
20 | //! }); |
21 | //! | |
22 | //! println!("first phone number: {}", john["phones"][0]); | |
23 | //! | |
24 | //! // Convert to a string of JSON and print it out | |
25 | //! println!("{}", john.to_string()); | |
26 | //! } | |
27 | //! ``` | |
28 | //! | |
29 | //! The `Value::to_string()` function converts a `serde_json::Value` into a | |
30 | //! `String` of JSON text. | |
31 | //! | |
32 | //! One neat thing about the `json!` macro is that variables and expressions can | |
33 | //! be interpolated directly into the JSON value as you are building it. Serde | |
34 | //! will check at compile time that the value you are interpolating is able to | |
35 | //! be represented as JSON. | |
36 | //! | |
f035d41b | 37 | //! ``` |
416331ca | 38 | //! # use serde_json::json; |
041b39d2 XL |
39 | //! # |
40 | //! # fn random_phone() -> u16 { 0 } | |
41 | //! # | |
041b39d2 XL |
42 | //! let full_name = "John Doe"; |
43 | //! let age_last_year = 42; | |
44 | //! | |
45 | //! // The type of `john` is `serde_json::Value` | |
46 | //! let john = json!({ | |
416331ca XL |
47 | //! "name": full_name, |
48 | //! "age": age_last_year + 1, | |
49 | //! "phones": [ | |
50 | //! format!("+44 {}", random_phone()) | |
51 | //! ] | |
041b39d2 | 52 | //! }); |
041b39d2 XL |
53 | //! ``` |
54 | //! | |
55 | //! A string of JSON data can be parsed into a `serde_json::Value` by the | |
56 | //! [`serde_json::from_str`][from_str] function. There is also | |
0bf4aa26 | 57 | //! [`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and |
041b39d2 XL |
58 | //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or |
59 | //! a TCP stream. | |
60 | //! | |
f035d41b | 61 | //! ``` |
416331ca | 62 | //! use serde_json::{json, Value, Error}; |
041b39d2 XL |
63 | //! |
64 | //! fn untyped_example() -> Result<(), Error> { | |
65 | //! // Some JSON input data as a &str. Maybe this comes from the user. | |
416331ca XL |
66 | //! let data = r#" |
67 | //! { | |
68 | //! "name": "John Doe", | |
69 | //! "age": 43, | |
70 | //! "phones": [ | |
71 | //! "+44 1234567", | |
72 | //! "+44 2345678" | |
73 | //! ] | |
74 | //! }"#; | |
041b39d2 XL |
75 | //! |
76 | //! // Parse the string of data into serde_json::Value. | |
77 | //! let v: Value = serde_json::from_str(data)?; | |
78 | //! | |
79 | //! // Access parts of the data by indexing with square brackets. | |
80 | //! println!("Please call {} at the number {}", v["name"], v["phones"][0]); | |
81 | //! | |
82 | //! Ok(()) | |
83 | //! } | |
84 | //! # | |
f035d41b | 85 | //! # untyped_example().unwrap(); |
041b39d2 XL |
86 | //! ``` |
87 | //! | |
88 | //! [macro]: https://docs.serde.rs/serde_json/macro.json.html | |
89 | //! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html | |
90 | //! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html | |
91 | //! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html | |
92 | ||
f035d41b XL |
93 | use crate::error::Error; |
94 | use crate::io; | |
95 | use crate::lib::*; | |
041b39d2 | 96 | use serde::de::DeserializeOwned; |
83c7162d | 97 | use serde::ser::Serialize; |
041b39d2 | 98 | |
041b39d2 | 99 | pub use self::index::Index; |
f035d41b XL |
100 | pub use self::ser::Serializer; |
101 | pub use crate::map::Map; | |
102 | pub use crate::number::Number; | |
041b39d2 | 103 | |
f035d41b XL |
104 | #[cfg(feature = "raw_value")] |
105 | pub use crate::raw::{to_raw_value, RawValue}; | |
041b39d2 XL |
106 | |
107 | /// Represents any valid JSON value. | |
108 | /// | |
6a06907d | 109 | /// See the [`serde_json::value` module documentation](self) for usage examples. |
f035d41b | 110 | #[derive(Clone, Eq, PartialEq)] |
041b39d2 XL |
111 | pub enum Value { |
112 | /// Represents a JSON null value. | |
113 | /// | |
f035d41b | 114 | /// ``` |
416331ca | 115 | /// # use serde_json::json; |
041b39d2 | 116 | /// # |
041b39d2 | 117 | /// let v = json!(null); |
041b39d2 XL |
118 | /// ``` |
119 | Null, | |
120 | ||
121 | /// Represents a JSON boolean. | |
122 | /// | |
f035d41b | 123 | /// ``` |
416331ca | 124 | /// # use serde_json::json; |
041b39d2 | 125 | /// # |
041b39d2 | 126 | /// let v = json!(true); |
041b39d2 XL |
127 | /// ``` |
128 | Bool(bool), | |
129 | ||
130 | /// Represents a JSON number, whether integer or floating point. | |
131 | /// | |
f035d41b | 132 | /// ``` |
416331ca | 133 | /// # use serde_json::json; |
041b39d2 | 134 | /// # |
041b39d2 | 135 | /// let v = json!(12.5); |
041b39d2 XL |
136 | /// ``` |
137 | Number(Number), | |
138 | ||
139 | /// Represents a JSON string. | |
140 | /// | |
f035d41b | 141 | /// ``` |
416331ca | 142 | /// # use serde_json::json; |
041b39d2 | 143 | /// # |
041b39d2 | 144 | /// let v = json!("a string"); |
041b39d2 XL |
145 | /// ``` |
146 | String(String), | |
147 | ||
148 | /// Represents a JSON array. | |
149 | /// | |
f035d41b | 150 | /// ``` |
416331ca | 151 | /// # use serde_json::json; |
041b39d2 | 152 | /// # |
041b39d2 | 153 | /// let v = json!(["an", "array"]); |
041b39d2 XL |
154 | /// ``` |
155 | Array(Vec<Value>), | |
156 | ||
157 | /// Represents a JSON object. | |
158 | /// | |
159 | /// By default the map is backed by a BTreeMap. Enable the `preserve_order` | |
8faf50e0 | 160 | /// feature of serde_json to use IndexMap instead, which preserves |
041b39d2 XL |
161 | /// entries in the order they are inserted into the map. In particular, this |
162 | /// allows JSON data to be deserialized into a Value and serialized to a | |
163 | /// string while retaining the order of map keys in the input. | |
164 | /// | |
f035d41b | 165 | /// ``` |
416331ca | 166 | /// # use serde_json::json; |
041b39d2 | 167 | /// # |
041b39d2 | 168 | /// let v = json!({ "an": "object" }); |
041b39d2 XL |
169 | /// ``` |
170 | Object(Map<String, Value>), | |
171 | } | |
172 | ||
2c00a5a8 XL |
173 | impl Debug for Value { |
174 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | |
175 | match *self { | |
83c7162d XL |
176 | Value::Null => formatter.debug_tuple("Null").finish(), |
177 | Value::Bool(v) => formatter.debug_tuple("Bool").field(&v).finish(), | |
178 | Value::Number(ref v) => Debug::fmt(v, formatter), | |
179 | Value::String(ref v) => formatter.debug_tuple("String").field(v).finish(), | |
f035d41b XL |
180 | Value::Array(ref v) => { |
181 | formatter.write_str("Array(")?; | |
182 | Debug::fmt(v, formatter)?; | |
183 | formatter.write_str(")") | |
184 | } | |
185 | Value::Object(ref v) => { | |
186 | formatter.write_str("Object(")?; | |
187 | Debug::fmt(v, formatter)?; | |
188 | formatter.write_str(")") | |
189 | } | |
2c00a5a8 XL |
190 | } |
191 | } | |
192 | } | |
193 | ||
8faf50e0 XL |
194 | impl fmt::Display for Value { |
195 | /// Display a JSON value as a string. | |
196 | /// | |
f035d41b | 197 | /// ``` |
416331ca | 198 | /// # use serde_json::json; |
8faf50e0 | 199 | /// # |
8faf50e0 XL |
200 | /// let json = json!({ "city": "London", "street": "10 Downing Street" }); |
201 | /// | |
202 | /// // Compact format: | |
203 | /// // | |
204 | /// // {"city":"London","street":"10 Downing Street"} | |
205 | /// let compact = format!("{}", json); | |
206 | /// assert_eq!(compact, | |
207 | /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}"); | |
208 | /// | |
209 | /// // Pretty format: | |
210 | /// // | |
211 | /// // { | |
212 | /// // "city": "London", | |
213 | /// // "street": "10 Downing Street" | |
214 | /// // } | |
215 | /// let pretty = format!("{:#}", json); | |
216 | /// assert_eq!(pretty, | |
217 | /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); | |
8faf50e0 XL |
218 | /// ``` |
219 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
6a06907d XL |
220 | struct WriterFormatter<'a, 'b: 'a> { |
221 | inner: &'a mut fmt::Formatter<'b>, | |
222 | } | |
223 | ||
224 | impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { | |
225 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
226 | // Safety: the serializer below only emits valid utf8 when using | |
227 | // the default formatter. | |
228 | let s = unsafe { str::from_utf8_unchecked(buf) }; | |
229 | tri!(self.inner.write_str(s).map_err(io_error)); | |
230 | Ok(buf.len()) | |
231 | } | |
232 | ||
233 | fn flush(&mut self) -> io::Result<()> { | |
234 | Ok(()) | |
235 | } | |
236 | } | |
237 | ||
238 | fn io_error(_: fmt::Error) -> io::Error { | |
239 | // Error value does not matter because Display impl just maps it | |
240 | // back to fmt::Error. | |
241 | io::Error::new(io::ErrorKind::Other, "fmt error") | |
242 | } | |
243 | ||
8faf50e0 XL |
244 | let alternate = f.alternate(); |
245 | let mut wr = WriterFormatter { inner: f }; | |
246 | if alternate { | |
247 | // {:#} | |
248 | super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) | |
249 | } else { | |
250 | // {} | |
251 | super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) | |
252 | } | |
253 | } | |
254 | } | |
255 | ||
041b39d2 XL |
256 | fn parse_index(s: &str) -> Option<usize> { |
257 | if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { | |
258 | return None; | |
259 | } | |
260 | s.parse().ok() | |
261 | } | |
262 | ||
263 | impl Value { | |
264 | /// Index into a JSON array or map. A string index can be used to access a | |
265 | /// value in a map, and a usize index can be used to access an element of an | |
266 | /// array. | |
267 | /// | |
268 | /// Returns `None` if the type of `self` does not match the type of the | |
269 | /// index, for example if the index is a string and `self` is an array or a | |
270 | /// number. Also returns `None` if the given key does not exist in the map | |
271 | /// or the given index is not within the bounds of the array. | |
272 | /// | |
f035d41b | 273 | /// ``` |
416331ca | 274 | /// # use serde_json::json; |
041b39d2 | 275 | /// # |
041b39d2 XL |
276 | /// let object = json!({ "A": 65, "B": 66, "C": 67 }); |
277 | /// assert_eq!(*object.get("A").unwrap(), json!(65)); | |
278 | /// | |
279 | /// let array = json!([ "A", "B", "C" ]); | |
280 | /// assert_eq!(*array.get(2).unwrap(), json!("C")); | |
281 | /// | |
282 | /// assert_eq!(array.get("A"), None); | |
041b39d2 XL |
283 | /// ``` |
284 | /// | |
285 | /// Square brackets can also be used to index into a value in a more concise | |
286 | /// way. This returns `Value::Null` in cases where `get` would have returned | |
287 | /// `None`. | |
288 | /// | |
f035d41b | 289 | /// ``` |
416331ca | 290 | /// # use serde_json::json; |
041b39d2 | 291 | /// # |
041b39d2 XL |
292 | /// let object = json!({ |
293 | /// "A": ["a", "á", "à"], | |
294 | /// "B": ["b", "b́"], | |
295 | /// "C": ["c", "ć", "ć̣", "ḉ"], | |
296 | /// }); | |
297 | /// assert_eq!(object["B"][0], json!("b")); | |
298 | /// | |
299 | /// assert_eq!(object["D"], json!(null)); | |
300 | /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); | |
041b39d2 XL |
301 | /// ``` |
302 | pub fn get<I: Index>(&self, index: I) -> Option<&Value> { | |
303 | index.index_into(self) | |
304 | } | |
305 | ||
306 | /// Mutably index into a JSON array or map. A string index can be used to | |
307 | /// access a value in a map, and a usize index can be used to access an | |
308 | /// element of an array. | |
309 | /// | |
310 | /// Returns `None` if the type of `self` does not match the type of the | |
311 | /// index, for example if the index is a string and `self` is an array or a | |
312 | /// number. Also returns `None` if the given key does not exist in the map | |
313 | /// or the given index is not within the bounds of the array. | |
314 | /// | |
f035d41b | 315 | /// ``` |
416331ca | 316 | /// # use serde_json::json; |
041b39d2 | 317 | /// # |
041b39d2 XL |
318 | /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); |
319 | /// *object.get_mut("A").unwrap() = json!(69); | |
320 | /// | |
321 | /// let mut array = json!([ "A", "B", "C" ]); | |
322 | /// *array.get_mut(2).unwrap() = json!("D"); | |
041b39d2 XL |
323 | /// ``` |
324 | pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> { | |
325 | index.index_into_mut(self) | |
326 | } | |
327 | ||
328 | /// Returns true if the `Value` is an Object. Returns false otherwise. | |
329 | /// | |
330 | /// For any Value on which `is_object` returns true, `as_object` and | |
331 | /// `as_object_mut` are guaranteed to return the map representation of the | |
332 | /// object. | |
333 | /// | |
f035d41b | 334 | /// ``` |
416331ca | 335 | /// # use serde_json::json; |
041b39d2 | 336 | /// # |
041b39d2 XL |
337 | /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); |
338 | /// | |
339 | /// assert!(obj.is_object()); | |
340 | /// assert!(obj["a"].is_object()); | |
341 | /// | |
342 | /// // array, not an object | |
343 | /// assert!(!obj["b"].is_object()); | |
041b39d2 XL |
344 | /// ``` |
345 | pub fn is_object(&self) -> bool { | |
346 | self.as_object().is_some() | |
347 | } | |
348 | ||
349 | /// If the `Value` is an Object, returns the associated Map. Returns None | |
350 | /// otherwise. | |
351 | /// | |
f035d41b | 352 | /// ``` |
416331ca | 353 | /// # use serde_json::json; |
041b39d2 | 354 | /// # |
041b39d2 XL |
355 | /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); |
356 | /// | |
357 | /// // The length of `{"nested": true}` is 1 entry. | |
358 | /// assert_eq!(v["a"].as_object().unwrap().len(), 1); | |
359 | /// | |
360 | /// // The array `["an", "array"]` is not an object. | |
361 | /// assert_eq!(v["b"].as_object(), None); | |
041b39d2 XL |
362 | /// ``` |
363 | pub fn as_object(&self) -> Option<&Map<String, Value>> { | |
364 | match *self { | |
365 | Value::Object(ref map) => Some(map), | |
366 | _ => None, | |
367 | } | |
368 | } | |
369 | ||
370 | /// If the `Value` is an Object, returns the associated mutable Map. | |
371 | /// Returns None otherwise. | |
372 | /// | |
f035d41b | 373 | /// ``` |
416331ca | 374 | /// # use serde_json::json; |
041b39d2 | 375 | /// # |
041b39d2 XL |
376 | /// let mut v = json!({ "a": { "nested": true } }); |
377 | /// | |
378 | /// v["a"].as_object_mut().unwrap().clear(); | |
379 | /// assert_eq!(v, json!({ "a": {} })); | |
041b39d2 XL |
380 | /// ``` |
381 | pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> { | |
382 | match *self { | |
383 | Value::Object(ref mut map) => Some(map), | |
384 | _ => None, | |
385 | } | |
386 | } | |
387 | ||
388 | /// Returns true if the `Value` is an Array. Returns false otherwise. | |
389 | /// | |
390 | /// For any Value on which `is_array` returns true, `as_array` and | |
391 | /// `as_array_mut` are guaranteed to return the vector representing the | |
392 | /// array. | |
393 | /// | |
f035d41b | 394 | /// ``` |
416331ca | 395 | /// # use serde_json::json; |
041b39d2 | 396 | /// # |
041b39d2 XL |
397 | /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); |
398 | /// | |
399 | /// assert!(obj["a"].is_array()); | |
400 | /// | |
401 | /// // an object, not an array | |
402 | /// assert!(!obj["b"].is_array()); | |
041b39d2 XL |
403 | /// ``` |
404 | pub fn is_array(&self) -> bool { | |
405 | self.as_array().is_some() | |
406 | } | |
407 | ||
408 | /// If the `Value` is an Array, returns the associated vector. Returns None | |
409 | /// otherwise. | |
410 | /// | |
f035d41b | 411 | /// ``` |
416331ca | 412 | /// # use serde_json::json; |
041b39d2 | 413 | /// # |
041b39d2 XL |
414 | /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); |
415 | /// | |
416 | /// // The length of `["an", "array"]` is 2 elements. | |
417 | /// assert_eq!(v["a"].as_array().unwrap().len(), 2); | |
418 | /// | |
419 | /// // The object `{"an": "object"}` is not an array. | |
420 | /// assert_eq!(v["b"].as_array(), None); | |
041b39d2 XL |
421 | /// ``` |
422 | pub fn as_array(&self) -> Option<&Vec<Value>> { | |
423 | match *self { | |
424 | Value::Array(ref array) => Some(&*array), | |
425 | _ => None, | |
426 | } | |
427 | } | |
428 | ||
429 | /// If the `Value` is an Array, returns the associated mutable vector. | |
430 | /// Returns None otherwise. | |
431 | /// | |
f035d41b | 432 | /// ``` |
416331ca | 433 | /// # use serde_json::json; |
041b39d2 | 434 | /// # |
041b39d2 XL |
435 | /// let mut v = json!({ "a": ["an", "array"] }); |
436 | /// | |
437 | /// v["a"].as_array_mut().unwrap().clear(); | |
438 | /// assert_eq!(v, json!({ "a": [] })); | |
041b39d2 XL |
439 | /// ``` |
440 | pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> { | |
441 | match *self { | |
442 | Value::Array(ref mut list) => Some(list), | |
443 | _ => None, | |
444 | } | |
445 | } | |
446 | ||
447 | /// Returns true if the `Value` is a String. Returns false otherwise. | |
448 | /// | |
449 | /// For any Value on which `is_string` returns true, `as_str` is guaranteed | |
450 | /// to return the string slice. | |
451 | /// | |
f035d41b | 452 | /// ``` |
416331ca | 453 | /// # use serde_json::json; |
041b39d2 | 454 | /// # |
041b39d2 XL |
455 | /// let v = json!({ "a": "some string", "b": false }); |
456 | /// | |
457 | /// assert!(v["a"].is_string()); | |
458 | /// | |
459 | /// // The boolean `false` is not a string. | |
460 | /// assert!(!v["b"].is_string()); | |
041b39d2 XL |
461 | /// ``` |
462 | pub fn is_string(&self) -> bool { | |
463 | self.as_str().is_some() | |
464 | } | |
465 | ||
466 | /// If the `Value` is a String, returns the associated str. Returns None | |
467 | /// otherwise. | |
468 | /// | |
f035d41b | 469 | /// ``` |
416331ca | 470 | /// # use serde_json::json; |
041b39d2 | 471 | /// # |
041b39d2 XL |
472 | /// let v = json!({ "a": "some string", "b": false }); |
473 | /// | |
474 | /// assert_eq!(v["a"].as_str(), Some("some string")); | |
475 | /// | |
476 | /// // The boolean `false` is not a string. | |
477 | /// assert_eq!(v["b"].as_str(), None); | |
abe05a73 XL |
478 | /// |
479 | /// // JSON values are printed in JSON representation, so strings are in quotes. | |
480 | /// // | |
481 | /// // The value is: "some string" | |
482 | /// println!("The value is: {}", v["a"]); | |
483 | /// | |
484 | /// // Rust strings are printed without quotes. | |
485 | /// // | |
486 | /// // The value is: some string | |
487 | /// println!("The value is: {}", v["a"].as_str().unwrap()); | |
041b39d2 XL |
488 | /// ``` |
489 | pub fn as_str(&self) -> Option<&str> { | |
490 | match *self { | |
491 | Value::String(ref s) => Some(s), | |
492 | _ => None, | |
493 | } | |
494 | } | |
495 | ||
496 | /// Returns true if the `Value` is a Number. Returns false otherwise. | |
497 | /// | |
f035d41b | 498 | /// ``` |
416331ca | 499 | /// # use serde_json::json; |
041b39d2 | 500 | /// # |
041b39d2 XL |
501 | /// let v = json!({ "a": 1, "b": "2" }); |
502 | /// | |
503 | /// assert!(v["a"].is_number()); | |
504 | /// | |
505 | /// // The string `"2"` is a string, not a number. | |
506 | /// assert!(!v["b"].is_number()); | |
041b39d2 XL |
507 | /// ``` |
508 | pub fn is_number(&self) -> bool { | |
509 | match *self { | |
510 | Value::Number(_) => true, | |
511 | _ => false, | |
512 | } | |
513 | } | |
514 | ||
515 | /// Returns true if the `Value` is an integer between `i64::MIN` and | |
516 | /// `i64::MAX`. | |
517 | /// | |
518 | /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to | |
519 | /// return the integer value. | |
520 | /// | |
f035d41b | 521 | /// ``` |
416331ca | 522 | /// # use serde_json::json; |
041b39d2 | 523 | /// # |
8faf50e0 | 524 | /// let big = i64::max_value() as u64 + 10; |
041b39d2 XL |
525 | /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); |
526 | /// | |
527 | /// assert!(v["a"].is_i64()); | |
528 | /// | |
529 | /// // Greater than i64::MAX. | |
530 | /// assert!(!v["b"].is_i64()); | |
531 | /// | |
532 | /// // Numbers with a decimal point are not considered integers. | |
533 | /// assert!(!v["c"].is_i64()); | |
041b39d2 XL |
534 | /// ``` |
535 | pub fn is_i64(&self) -> bool { | |
536 | match *self { | |
537 | Value::Number(ref n) => n.is_i64(), | |
538 | _ => false, | |
539 | } | |
540 | } | |
541 | ||
542 | /// Returns true if the `Value` is an integer between zero and `u64::MAX`. | |
543 | /// | |
544 | /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to | |
545 | /// return the integer value. | |
546 | /// | |
f035d41b | 547 | /// ``` |
416331ca | 548 | /// # use serde_json::json; |
041b39d2 | 549 | /// # |
041b39d2 XL |
550 | /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); |
551 | /// | |
552 | /// assert!(v["a"].is_u64()); | |
553 | /// | |
554 | /// // Negative integer. | |
555 | /// assert!(!v["b"].is_u64()); | |
556 | /// | |
557 | /// // Numbers with a decimal point are not considered integers. | |
558 | /// assert!(!v["c"].is_u64()); | |
041b39d2 XL |
559 | /// ``` |
560 | pub fn is_u64(&self) -> bool { | |
561 | match *self { | |
562 | Value::Number(ref n) => n.is_u64(), | |
563 | _ => false, | |
564 | } | |
565 | } | |
566 | ||
567 | /// Returns true if the `Value` is a number that can be represented by f64. | |
568 | /// | |
569 | /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to | |
570 | /// return the floating point value. | |
571 | /// | |
572 | /// Currently this function returns true if and only if both `is_i64` and | |
573 | /// `is_u64` return false but this is not a guarantee in the future. | |
574 | /// | |
f035d41b | 575 | /// ``` |
416331ca | 576 | /// # use serde_json::json; |
041b39d2 | 577 | /// # |
041b39d2 XL |
578 | /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); |
579 | /// | |
580 | /// assert!(v["a"].is_f64()); | |
581 | /// | |
582 | /// // Integers. | |
583 | /// assert!(!v["b"].is_f64()); | |
584 | /// assert!(!v["c"].is_f64()); | |
041b39d2 XL |
585 | /// ``` |
586 | pub fn is_f64(&self) -> bool { | |
587 | match *self { | |
588 | Value::Number(ref n) => n.is_f64(), | |
589 | _ => false, | |
590 | } | |
591 | } | |
592 | ||
593 | /// If the `Value` is an integer, represent it as i64 if possible. Returns | |
594 | /// None otherwise. | |
595 | /// | |
f035d41b | 596 | /// ``` |
416331ca | 597 | /// # use serde_json::json; |
041b39d2 | 598 | /// # |
8faf50e0 | 599 | /// let big = i64::max_value() as u64 + 10; |
041b39d2 XL |
600 | /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); |
601 | /// | |
602 | /// assert_eq!(v["a"].as_i64(), Some(64)); | |
603 | /// assert_eq!(v["b"].as_i64(), None); | |
604 | /// assert_eq!(v["c"].as_i64(), None); | |
041b39d2 XL |
605 | /// ``` |
606 | pub fn as_i64(&self) -> Option<i64> { | |
607 | match *self { | |
608 | Value::Number(ref n) => n.as_i64(), | |
609 | _ => None, | |
610 | } | |
611 | } | |
612 | ||
613 | /// If the `Value` is an integer, represent it as u64 if possible. Returns | |
614 | /// None otherwise. | |
615 | /// | |
f035d41b | 616 | /// ``` |
416331ca | 617 | /// # use serde_json::json; |
041b39d2 | 618 | /// # |
041b39d2 XL |
619 | /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); |
620 | /// | |
621 | /// assert_eq!(v["a"].as_u64(), Some(64)); | |
622 | /// assert_eq!(v["b"].as_u64(), None); | |
623 | /// assert_eq!(v["c"].as_u64(), None); | |
041b39d2 XL |
624 | /// ``` |
625 | pub fn as_u64(&self) -> Option<u64> { | |
626 | match *self { | |
627 | Value::Number(ref n) => n.as_u64(), | |
628 | _ => None, | |
629 | } | |
630 | } | |
631 | ||
632 | /// If the `Value` is a number, represent it as f64 if possible. Returns | |
633 | /// None otherwise. | |
634 | /// | |
f035d41b | 635 | /// ``` |
416331ca | 636 | /// # use serde_json::json; |
041b39d2 | 637 | /// # |
041b39d2 XL |
638 | /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); |
639 | /// | |
640 | /// assert_eq!(v["a"].as_f64(), Some(256.0)); | |
641 | /// assert_eq!(v["b"].as_f64(), Some(64.0)); | |
642 | /// assert_eq!(v["c"].as_f64(), Some(-64.0)); | |
041b39d2 XL |
643 | /// ``` |
644 | pub fn as_f64(&self) -> Option<f64> { | |
645 | match *self { | |
646 | Value::Number(ref n) => n.as_f64(), | |
647 | _ => None, | |
648 | } | |
649 | } | |
650 | ||
651 | /// Returns true if the `Value` is a Boolean. Returns false otherwise. | |
652 | /// | |
653 | /// For any Value on which `is_boolean` returns true, `as_bool` is | |
654 | /// guaranteed to return the boolean value. | |
655 | /// | |
f035d41b | 656 | /// ``` |
416331ca | 657 | /// # use serde_json::json; |
041b39d2 | 658 | /// # |
041b39d2 XL |
659 | /// let v = json!({ "a": false, "b": "false" }); |
660 | /// | |
661 | /// assert!(v["a"].is_boolean()); | |
662 | /// | |
663 | /// // The string `"false"` is a string, not a boolean. | |
664 | /// assert!(!v["b"].is_boolean()); | |
041b39d2 XL |
665 | /// ``` |
666 | pub fn is_boolean(&self) -> bool { | |
667 | self.as_bool().is_some() | |
668 | } | |
669 | ||
670 | /// If the `Value` is a Boolean, returns the associated bool. Returns None | |
671 | /// otherwise. | |
672 | /// | |
f035d41b | 673 | /// ``` |
416331ca | 674 | /// # use serde_json::json; |
041b39d2 | 675 | /// # |
041b39d2 XL |
676 | /// let v = json!({ "a": false, "b": "false" }); |
677 | /// | |
678 | /// assert_eq!(v["a"].as_bool(), Some(false)); | |
679 | /// | |
680 | /// // The string `"false"` is a string, not a boolean. | |
681 | /// assert_eq!(v["b"].as_bool(), None); | |
041b39d2 XL |
682 | /// ``` |
683 | pub fn as_bool(&self) -> Option<bool> { | |
684 | match *self { | |
685 | Value::Bool(b) => Some(b), | |
686 | _ => None, | |
687 | } | |
688 | } | |
689 | ||
690 | /// Returns true if the `Value` is a Null. Returns false otherwise. | |
691 | /// | |
692 | /// For any Value on which `is_null` returns true, `as_null` is guaranteed | |
693 | /// to return `Some(())`. | |
694 | /// | |
f035d41b | 695 | /// ``` |
416331ca | 696 | /// # use serde_json::json; |
041b39d2 | 697 | /// # |
041b39d2 XL |
698 | /// let v = json!({ "a": null, "b": false }); |
699 | /// | |
700 | /// assert!(v["a"].is_null()); | |
701 | /// | |
702 | /// // The boolean `false` is not null. | |
703 | /// assert!(!v["b"].is_null()); | |
041b39d2 XL |
704 | /// ``` |
705 | pub fn is_null(&self) -> bool { | |
706 | self.as_null().is_some() | |
707 | } | |
708 | ||
709 | /// If the `Value` is a Null, returns (). Returns None otherwise. | |
710 | /// | |
f035d41b | 711 | /// ``` |
416331ca | 712 | /// # use serde_json::json; |
041b39d2 | 713 | /// # |
041b39d2 XL |
714 | /// let v = json!({ "a": null, "b": false }); |
715 | /// | |
716 | /// assert_eq!(v["a"].as_null(), Some(())); | |
717 | /// | |
718 | /// // The boolean `false` is not null. | |
719 | /// assert_eq!(v["b"].as_null(), None); | |
041b39d2 XL |
720 | /// ``` |
721 | pub fn as_null(&self) -> Option<()> { | |
722 | match *self { | |
723 | Value::Null => Some(()), | |
724 | _ => None, | |
725 | } | |
726 | } | |
727 | ||
728 | /// Looks up a value by a JSON Pointer. | |
729 | /// | |
730 | /// JSON Pointer defines a string syntax for identifying a specific value | |
731 | /// within a JavaScript Object Notation (JSON) document. | |
732 | /// | |
733 | /// A Pointer is a Unicode string with the reference tokens separated by `/`. | |
734 | /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The | |
735 | /// addressed value is returned and if there is no such value `None` is | |
736 | /// returned. | |
737 | /// | |
738 | /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). | |
739 | /// | |
740 | /// # Examples | |
741 | /// | |
f035d41b | 742 | /// ``` |
416331ca | 743 | /// # use serde_json::json; |
041b39d2 | 744 | /// # |
041b39d2 XL |
745 | /// let data = json!({ |
746 | /// "x": { | |
747 | /// "y": ["z", "zz"] | |
748 | /// } | |
749 | /// }); | |
750 | /// | |
751 | /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz")); | |
752 | /// assert_eq!(data.pointer("/a/b/c"), None); | |
041b39d2 | 753 | /// ``` |
f035d41b | 754 | pub fn pointer(&self, pointer: &str) -> Option<&Value> { |
5869c6ff | 755 | if pointer.is_empty() { |
041b39d2 XL |
756 | return Some(self); |
757 | } | |
758 | if !pointer.starts_with('/') { | |
759 | return None; | |
760 | } | |
761 | let tokens = pointer | |
762 | .split('/') | |
763 | .skip(1) | |
764 | .map(|x| x.replace("~1", "/").replace("~0", "~")); | |
765 | let mut target = self; | |
766 | ||
767 | for token in tokens { | |
768 | let target_opt = match *target { | |
769 | Value::Object(ref map) => map.get(&token), | |
770 | Value::Array(ref list) => parse_index(&token).and_then(|x| list.get(x)), | |
771 | _ => return None, | |
772 | }; | |
773 | if let Some(t) = target_opt { | |
774 | target = t; | |
775 | } else { | |
776 | return None; | |
777 | } | |
778 | } | |
779 | Some(target) | |
780 | } | |
781 | ||
782 | /// Looks up a value by a JSON Pointer and returns a mutable reference to | |
783 | /// that value. | |
784 | /// | |
785 | /// JSON Pointer defines a string syntax for identifying a specific value | |
786 | /// within a JavaScript Object Notation (JSON) document. | |
787 | /// | |
788 | /// A Pointer is a Unicode string with the reference tokens separated by `/`. | |
789 | /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The | |
790 | /// addressed value is returned and if there is no such value `None` is | |
791 | /// returned. | |
792 | /// | |
793 | /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). | |
794 | /// | |
795 | /// # Example of Use | |
796 | /// | |
f035d41b | 797 | /// ``` |
041b39d2 | 798 | /// use serde_json::Value; |
041b39d2 XL |
799 | /// |
800 | /// fn main() { | |
801 | /// let s = r#"{"x": 1.0, "y": 2.0}"#; | |
802 | /// let mut value: Value = serde_json::from_str(s).unwrap(); | |
803 | /// | |
804 | /// // Check value using read-only pointer | |
805 | /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); | |
806 | /// // Change value with direct assignment | |
807 | /// *value.pointer_mut("/x").unwrap() = 1.5.into(); | |
808 | /// // Check that new value was written | |
809 | /// assert_eq!(value.pointer("/x"), Some(&1.5.into())); | |
f035d41b XL |
810 | /// // Or change the value only if it exists |
811 | /// value.pointer_mut("/x").map(|v| *v = 1.5.into()); | |
041b39d2 XL |
812 | /// |
813 | /// // "Steal" ownership of a value. Can replace with any valid Value. | |
0531ce1d | 814 | /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap(); |
041b39d2 XL |
815 | /// assert_eq!(old_x, 1.5); |
816 | /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null); | |
817 | /// } | |
818 | /// ``` | |
f035d41b | 819 | pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> { |
5869c6ff | 820 | if pointer.is_empty() { |
041b39d2 XL |
821 | return Some(self); |
822 | } | |
823 | if !pointer.starts_with('/') { | |
824 | return None; | |
825 | } | |
826 | let tokens = pointer | |
827 | .split('/') | |
828 | .skip(1) | |
829 | .map(|x| x.replace("~1", "/").replace("~0", "~")); | |
830 | let mut target = self; | |
831 | ||
832 | for token in tokens { | |
833 | // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop | |
834 | // this once-per-loop binding makes the scope clearer and circumvents the error | |
835 | let target_once = target; | |
836 | let target_opt = match *target_once { | |
837 | Value::Object(ref mut map) => map.get_mut(&token), | |
838 | Value::Array(ref mut list) => { | |
839 | parse_index(&token).and_then(move |x| list.get_mut(x)) | |
840 | } | |
841 | _ => return None, | |
842 | }; | |
843 | if let Some(t) = target_opt { | |
844 | target = t; | |
845 | } else { | |
846 | return None; | |
847 | } | |
848 | } | |
849 | Some(target) | |
850 | } | |
0531ce1d XL |
851 | |
852 | /// Takes the value out of the `Value`, leaving a `Null` in its place. | |
853 | /// | |
f035d41b | 854 | /// ``` |
416331ca | 855 | /// # use serde_json::json; |
0531ce1d | 856 | /// # |
0531ce1d XL |
857 | /// let mut v = json!({ "x": "y" }); |
858 | /// assert_eq!(v["x"].take(), json!("y")); | |
859 | /// assert_eq!(v, json!({ "x": null })); | |
0531ce1d XL |
860 | /// ``` |
861 | pub fn take(&mut self) -> Value { | |
862 | mem::replace(self, Value::Null) | |
863 | } | |
041b39d2 XL |
864 | } |
865 | ||
866 | /// The default value is `Value::Null`. | |
867 | /// | |
868 | /// This is useful for handling omitted `Value` fields when deserializing. | |
869 | /// | |
870 | /// # Examples | |
871 | /// | |
f035d41b | 872 | /// ``` |
416331ca | 873 | /// # use serde::Deserialize; |
041b39d2 XL |
874 | /// use serde_json::Value; |
875 | /// | |
876 | /// #[derive(Deserialize)] | |
877 | /// struct Settings { | |
878 | /// level: i32, | |
879 | /// #[serde(default)] | |
880 | /// extras: Value, | |
881 | /// } | |
882 | /// | |
883 | /// # fn try_main() -> Result<(), serde_json::Error> { | |
884 | /// let data = r#" { "level": 42 } "#; | |
885 | /// let s: Settings = serde_json::from_str(data)?; | |
886 | /// | |
887 | /// assert_eq!(s.level, 42); | |
888 | /// assert_eq!(s.extras, Value::Null); | |
889 | /// # | |
890 | /// # Ok(()) | |
891 | /// # } | |
892 | /// # | |
f035d41b | 893 | /// # try_main().unwrap() |
041b39d2 XL |
894 | /// ``` |
895 | impl Default for Value { | |
896 | fn default() -> Value { | |
897 | Value::Null | |
898 | } | |
899 | } | |
900 | ||
83c7162d XL |
901 | mod de; |
902 | mod from; | |
041b39d2 XL |
903 | mod index; |
904 | mod partial_eq; | |
041b39d2 | 905 | mod ser; |
041b39d2 XL |
906 | |
907 | /// Convert a `T` into `serde_json::Value` which is an enum that can represent | |
908 | /// any valid JSON data. | |
909 | /// | |
416331ca | 910 | /// # Example |
041b39d2 | 911 | /// |
f035d41b | 912 | /// ``` |
416331ca XL |
913 | /// use serde::Serialize; |
914 | /// use serde_json::json; | |
041b39d2 XL |
915 | /// |
916 | /// use std::error::Error; | |
917 | /// | |
918 | /// #[derive(Serialize)] | |
919 | /// struct User { | |
920 | /// fingerprint: String, | |
921 | /// location: String, | |
922 | /// } | |
923 | /// | |
924 | /// fn compare_json_values() -> Result<(), Box<Error>> { | |
925 | /// let u = User { | |
926 | /// fingerprint: "0xF9BA143B95FF6D82".to_owned(), | |
927 | /// location: "Menlo Park, CA".to_owned(), | |
928 | /// }; | |
929 | /// | |
930 | /// // The type of `expected` is `serde_json::Value` | |
931 | /// let expected = json!({ | |
416331ca XL |
932 | /// "fingerprint": "0xF9BA143B95FF6D82", |
933 | /// "location": "Menlo Park, CA", | |
934 | /// }); | |
041b39d2 XL |
935 | /// |
936 | /// let v = serde_json::to_value(u).unwrap(); | |
937 | /// assert_eq!(v, expected); | |
938 | /// | |
939 | /// Ok(()) | |
940 | /// } | |
941 | /// # | |
f035d41b | 942 | /// # compare_json_values().unwrap(); |
041b39d2 XL |
943 | /// ``` |
944 | /// | |
945 | /// # Errors | |
946 | /// | |
947 | /// This conversion can fail if `T`'s implementation of `Serialize` decides to | |
948 | /// fail, or if `T` contains a map with non-string keys. | |
949 | /// | |
f035d41b | 950 | /// ``` |
041b39d2 XL |
951 | /// use std::collections::BTreeMap; |
952 | /// | |
953 | /// fn main() { | |
954 | /// // The keys in this map are vectors, not strings. | |
955 | /// let mut map = BTreeMap::new(); | |
956 | /// map.insert(vec![32, 64], "x86"); | |
957 | /// | |
958 | /// println!("{}", serde_json::to_value(map).unwrap_err()); | |
959 | /// } | |
960 | /// ``` | |
041b39d2 XL |
961 | // Taking by value is more friendly to iterator adapters, option and result |
962 | // consumers, etc. See https://github.com/serde-rs/json/pull/149. | |
963 | pub fn to_value<T>(value: T) -> Result<Value, Error> | |
964 | where | |
965 | T: Serialize, | |
966 | { | |
967 | value.serialize(Serializer) | |
968 | } | |
969 | ||
970 | /// Interpret a `serde_json::Value` as an instance of type `T`. | |
971 | /// | |
416331ca | 972 | /// # Example |
041b39d2 | 973 | /// |
f035d41b | 974 | /// ``` |
416331ca XL |
975 | /// use serde::Deserialize; |
976 | /// use serde_json::json; | |
041b39d2 XL |
977 | /// |
978 | /// #[derive(Deserialize, Debug)] | |
979 | /// struct User { | |
980 | /// fingerprint: String, | |
981 | /// location: String, | |
982 | /// } | |
983 | /// | |
984 | /// fn main() { | |
985 | /// // The type of `j` is `serde_json::Value` | |
986 | /// let j = json!({ | |
416331ca XL |
987 | /// "fingerprint": "0xF9BA143B95FF6D82", |
988 | /// "location": "Menlo Park, CA" | |
989 | /// }); | |
041b39d2 XL |
990 | /// |
991 | /// let u: User = serde_json::from_value(j).unwrap(); | |
992 | /// println!("{:#?}", u); | |
993 | /// } | |
994 | /// ``` | |
416331ca XL |
995 | /// |
996 | /// # Errors | |
997 | /// | |
998 | /// This conversion can fail if the structure of the Value does not match the | |
999 | /// structure expected by `T`, for example if `T` is a struct type but the Value | |
1000 | /// contains something other than a JSON map. It can also fail if the structure | |
1001 | /// is correct but `T`'s implementation of `Deserialize` decides that something | |
1002 | /// is wrong with the data, for example required struct fields are missing from | |
1003 | /// the JSON map or some number is too big to fit in the expected primitive | |
1004 | /// type. | |
041b39d2 XL |
1005 | pub fn from_value<T>(value: Value) -> Result<T, Error> |
1006 | where | |
1007 | T: DeserializeOwned, | |
1008 | { | |
1009 | T::deserialize(value) | |
1010 | } |