1 use crate::ser::Serializer;
2 use crate::{Error, Mapping};
3 use serde::de::{Deserialize, DeserializeOwned};
4 use serde::Serialize;
5 use std::f64;
6 use std::hash::{Hash, Hasher};
7 use std::str::FromStr;
8 use yaml_rust::Yaml;
9
10 pub use self::index::Index;
11 pub use crate::number::Number;
12
13 /// Represents any valid YAML value.
14 #[derive(Clone, PartialOrd, Debug)]
15 pub enum Value {
16 /// Represents a YAML null value.
17 Null,
18 /// Represents a YAML boolean.
19 Bool(bool),
20 /// Represents a YAML numerical value, whether integer or floating point.
21 Number(Number),
22 /// Represents a YAML string.
23 String(String),
24 /// Represents a YAML sequence in which the elements are
25 /// `serde_yaml::Value`.
26 Sequence(Sequence),
27 /// Represents a YAML mapping in which the keys and values are both
28 /// `serde_yaml::Value`.
29 Mapping(Mapping),
30 }
31
32 /// The default value is `Value::Null`.
33 ///
34 /// This is useful for handling omitted `Value` fields when deserializing.
35 ///
36 /// # Examples
37 ///
38 /// ```
39 /// # use serde_derive::Deserialize;
40 /// use serde::Deserialize;
41 /// use serde_yaml::Value;
42 ///
43 /// #[derive(Deserialize)]
44 /// struct Settings {
45 /// level: i32,
46 /// #[serde(default)]
47 /// extras: Value,
48 /// }
49 ///
50 /// # fn try_main() -> Result<(), serde_yaml::Error> {
51 /// let data = r#" { "level": 42 } "#;
52 /// let s: Settings = serde_yaml::from_str(data)?;
53 ///
54 /// assert_eq!(s.level, 42);
55 /// assert_eq!(s.extras, Value::Null);
56 /// #
57 /// # Ok(())
58 /// # }
59 /// #
60 /// # fn main() {
61 /// # try_main().unwrap()
62 /// # }
63 /// ```
64 impl Default for Value {
default() -> Value65 fn default() -> Value {
66 Value::Null
67 }
68 }
69
70 /// A YAML sequence in which the elements are `serde_yaml::Value`.
71 pub type Sequence = Vec<Value>;
72
73 /// Convert a `T` into `serde_yaml::Value` which is an enum that can represent
74 /// any valid YAML data.
75 ///
76 /// This conversion can fail if `T`'s implementation of `Serialize` decides to
77 /// return an error.
78 ///
79 /// ```
80 /// # use serde_yaml::Value;
81 /// let val = serde_yaml::to_value("s").unwrap();
82 /// assert_eq!(val, Value::String("s".to_owned()));
83 /// ```
to_value<T>(value: T) -> Result<Value, Error> where T: Serialize,84 pub fn to_value<T>(value: T) -> Result<Value, Error>
85 where
86 T: Serialize,
87 {
88 value.serialize(Serializer).map(yaml_to_value)
89 }
90
91 /// Interpret a `serde_yaml::Value` as an instance of type `T`.
92 ///
93 /// This conversion can fail if the structure of the Value does not match the
94 /// structure expected by `T`, for example if `T` is a struct type but the Value
95 /// contains something other than a YAML map. It can also fail if the structure
96 /// is correct but `T`'s implementation of `Deserialize` decides that something
97 /// is wrong with the data, for example required struct fields are missing from
98 /// the YAML map or some number is too big to fit in the expected primitive
99 /// type.
100 ///
101 /// ```
102 /// # use serde_yaml::Value;
103 /// let val = Value::String("foo".to_owned());
104 /// let s: String = serde_yaml::from_value(val).unwrap();
105 /// assert_eq!("foo", s);
106 /// ```
from_value<T>(value: Value) -> Result<T, Error> where T: DeserializeOwned,107 pub fn from_value<T>(value: Value) -> Result<T, Error>
108 where
109 T: DeserializeOwned,
110 {
111 Deserialize::deserialize(value)
112 }
113
114 impl Value {
115 /// Index into a YAML sequence or map. A string index can be used to access
116 /// a value in a map, and a usize index can be used to access an element of
117 /// an sequence.
118 ///
119 /// Returns `None` if the type of `self` does not match the type of the
120 /// index, for example if the index is a string and `self` is a sequence or
121 /// a number. Also returns `None` if the given key does not exist in the map
122 /// or the given index is not within the bounds of the sequence.
123 ///
124 /// ```
125 /// # use serde_yaml::Value;
126 /// #
127 /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
128 /// #
129 /// let object: Value = yaml(r#"{ A: 65, B: 66, C: 67 }"#);
130 /// let x = object.get("A").unwrap();
131 /// assert_eq!(x, 65);
132 ///
133 /// let sequence: Value = yaml(r#"[ "A", "B", "C" ]"#);
134 /// let x = sequence.get(2).unwrap();
135 /// assert_eq!(x, &Value::String("C".into()));
136 ///
137 /// assert_eq!(sequence.get("A"), None);
138 /// ```
139 ///
140 /// Square brackets can also be used to index into a value in a more concise
141 /// way. This returns `Value::Null` in cases where `get` would have returned
142 /// `None`.
143 ///
144 /// ```
145 /// # use serde_yaml::Value;
146 /// #
147 /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
148 /// #
149 /// let object = yaml(r#"
150 /// ---
151 /// A: [a, á, à]
152 /// B: [b, b́]
153 /// C: [c, ć, ć̣, ḉ]
154 /// 42: true
155 /// "#);
156 /// assert_eq!(object["B"][0], Value::String("b".into()));
157 ///
158 /// assert_eq!(object[Value::String("D".into())], Value::Null);
159 /// assert_eq!(object["D"], Value::Null);
160 /// assert_eq!(object[0]["x"]["y"]["z"], Value::Null);
161 ///
162 /// assert_eq!(object[42], Value::Bool(true));
163 /// ```
get<I: Index>(&self, index: I) -> Option<&Value>164 pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
165 index.index_into(self)
166 }
167
168 /// Index into a YAML sequence or map. A string index can be used to access
169 /// a value in a map, and a usize index can be used to access an element of
170 /// an sequence.
171 ///
172 /// Returns `None` if the type of `self` does not match the type of the
173 /// index, for example if the index is a string and `self` is a sequence or
174 /// a number. Also returns `None` if the given key does not exist in the map
175 /// or the given index is not within the bounds of the sequence.
get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value>176 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
177 index.index_into_mut(self)
178 }
179
180 /// Returns true if the `Value` is a Null. Returns false otherwise.
181 ///
182 /// For any Value on which `is_null` returns true, `as_null` is guaranteed
183 /// to return `Some(())`.
184 ///
185 /// ```
186 /// # use serde_yaml::Value;
187 /// let v: Value = serde_yaml::from_str("null").unwrap();
188 /// assert!(v.is_null());
189 /// ```
190 ///
191 /// ```
192 /// # use serde_yaml::Value;
193 /// let v: Value = serde_yaml::from_str("false").unwrap();
194 /// assert!(!v.is_null());
195 /// ```
is_null(&self) -> bool196 pub fn is_null(&self) -> bool {
197 if let Value::Null = *self {
198 true
199 } else {
200 false
201 }
202 }
203
204 /// If the `Value` is a Null, returns (). Returns None otherwise.
205 ///
206 /// ```
207 /// # use serde_yaml::Value;
208 /// let v: Value = serde_yaml::from_str("null").unwrap();
209 /// assert_eq!(v.as_null(), Some(()));
210 /// ```
211 ///
212 /// ```
213 /// # use serde_yaml::Value;
214 /// let v: Value = serde_yaml::from_str("false").unwrap();
215 /// assert_eq!(v.as_null(), None);
216 /// ```
as_null(&self) -> Option<()>217 pub fn as_null(&self) -> Option<()> {
218 match *self {
219 Value::Null => Some(()),
220 _ => None,
221 }
222 }
223
224 /// Returns true if the `Value` is a Boolean. Returns false otherwise.
225 ///
226 /// For any Value on which `is_boolean` returns true, `as_bool` is
227 /// guaranteed to return the boolean value.
228 ///
229 /// ```
230 /// # use serde_yaml::Value;
231 /// let v: Value = serde_yaml::from_str("true").unwrap();
232 /// assert!(v.is_bool());
233 /// ```
234 ///
235 /// ```
236 /// # use serde_yaml::Value;
237 /// let v: Value = serde_yaml::from_str("42").unwrap();
238 /// assert!(!v.is_bool());
239 /// ```
is_bool(&self) -> bool240 pub fn is_bool(&self) -> bool {
241 self.as_bool().is_some()
242 }
243
244 /// If the `Value` is a Boolean, returns the associated bool. Returns None
245 /// otherwise.
246 ///
247 /// ```
248 /// # use serde_yaml::Value;
249 /// let v: Value = serde_yaml::from_str("true").unwrap();
250 /// assert_eq!(v.as_bool(), Some(true));
251 /// ```
252 ///
253 /// ```
254 /// # use serde_yaml::Value;
255 /// let v: Value = serde_yaml::from_str("42").unwrap();
256 /// assert_eq!(v.as_bool(), None);
257 /// ```
as_bool(&self) -> Option<bool>258 pub fn as_bool(&self) -> Option<bool> {
259 match *self {
260 Value::Bool(b) => Some(b),
261 _ => None,
262 }
263 }
264
265 /// Returns true if the `Value` is a Number. Returns false otherwise.
266 ///
267 /// ```
268 /// # use serde_yaml::Value;
269 /// let v: Value = serde_yaml::from_str("5").unwrap();
270 /// assert!(v.is_number());
271 /// ```
272 ///
273 /// ```
274 /// # use serde_yaml::Value;
275 /// let v: Value = serde_yaml::from_str("true").unwrap();
276 /// assert!(!v.is_number());
277 /// ```
is_number(&self) -> bool278 pub fn is_number(&self) -> bool {
279 match *self {
280 Value::Number(_) => true,
281 _ => false,
282 }
283 }
284
285 /// Returns true if the `Value` is an integer between `i64::MIN` and
286 /// `i64::MAX`.
287 ///
288 /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
289 /// return the integer value.
290 ///
291 /// ```
292 /// # use serde_yaml::Value;
293 /// let v: Value = serde_yaml::from_str("1337").unwrap();
294 /// assert!(v.is_i64());
295 /// ```
296 ///
297 /// ```
298 /// # use serde_yaml::Value;
299 /// let v: Value = serde_yaml::from_str("null").unwrap();
300 /// assert!(!v.is_i64());
301 /// ```
is_i64(&self) -> bool302 pub fn is_i64(&self) -> bool {
303 self.as_i64().is_some()
304 }
305
306 /// If the `Value` is an integer, represent it as i64 if possible. Returns
307 /// None otherwise.
308 ///
309 /// ```
310 /// # use serde_yaml::Value;
311 /// let v: Value = serde_yaml::from_str("1337").unwrap();
312 /// assert_eq!(v.as_i64(), Some(1337));
313 /// ```
314 ///
315 /// ```
316 /// # use serde_yaml::Value;
317 /// let v: Value = serde_yaml::from_str("false").unwrap();
318 /// assert_eq!(v.as_i64(), None);
319 /// ```
as_i64(&self) -> Option<i64>320 pub fn as_i64(&self) -> Option<i64> {
321 match *self {
322 Value::Number(ref n) => n.as_i64(),
323 _ => None,
324 }
325 }
326
327 /// Returns true if the `Value` is an integer between `u64::MIN` and
328 /// `u64::MAX`.
329 ///
330 /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
331 /// return the integer value.
332 ///
333 /// ```
334 /// # use serde_yaml::Value;
335 /// let v: Value = serde_yaml::from_str("1337").unwrap();
336 /// assert!(v.is_u64());
337 /// ```
338 ///
339 /// ```
340 /// # use serde_yaml::Value;
341 /// let v: Value = serde_yaml::from_str("null").unwrap();
342 /// assert!(!v.is_u64());
343 /// ```
is_u64(&self) -> bool344 pub fn is_u64(&self) -> bool {
345 self.as_u64().is_some()
346 }
347
348 /// If the `Value` is an integer, represent it as u64 if possible. Returns
349 /// None otherwise.
350 ///
351 /// ```
352 /// # use serde_yaml::Value;
353 /// let v: Value = serde_yaml::from_str("1337").unwrap();
354 /// assert_eq!(v.as_u64(), Some(1337));
355 /// ```
356 ///
357 /// ```
358 /// # use serde_yaml::Value;
359 /// let v: Value = serde_yaml::from_str("false").unwrap();
360 /// assert_eq!(v.as_u64(), None);
361 /// ```
as_u64(&self) -> Option<u64>362 pub fn as_u64(&self) -> Option<u64> {
363 match *self {
364 Value::Number(ref n) => n.as_u64(),
365 _ => None,
366 }
367 }
368
369 /// Returns true if the `Value` is a number that can be represented by f64.
370 ///
371 /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
372 /// return the floating point value.
373 ///
374 /// Currently this function returns true if and only if both `is_i64` and
375 /// `is_u64` return false but this is not a guarantee in the future.
376 ///
377 /// ```
378 /// # use serde_yaml::Value;
379 /// let v: Value = serde_yaml::from_str("256.01").unwrap();
380 /// assert!(v.is_f64());
381 /// ```
382 ///
383 /// ```
384 /// # use serde_yaml::Value;
385 /// let v: Value = serde_yaml::from_str("true").unwrap();
386 /// assert!(!v.is_f64());
387 /// ```
is_f64(&self) -> bool388 pub fn is_f64(&self) -> bool {
389 match *self {
390 Value::Number(ref n) => n.is_f64(),
391 _ => false,
392 }
393 }
394
395 /// If the `Value` is a number, represent it as f64 if possible. Returns
396 /// None otherwise.
397 ///
398 /// ```
399 /// # use serde_yaml::Value;
400 /// let v: Value = serde_yaml::from_str("13.37").unwrap();
401 /// assert_eq!(v.as_f64(), Some(13.37));
402 /// ```
403 ///
404 /// ```
405 /// # use serde_yaml::Value;
406 /// let v: Value = serde_yaml::from_str("false").unwrap();
407 /// assert_eq!(v.as_f64(), None);
408 /// ```
as_f64(&self) -> Option<f64>409 pub fn as_f64(&self) -> Option<f64> {
410 match *self {
411 Value::Number(ref i) => i.as_f64(),
412 _ => None,
413 }
414 }
415
416 /// Returns true if the `Value` is a String. Returns false otherwise.
417 ///
418 /// For any Value on which `is_string` returns true, `as_str` is guaranteed
419 /// to return the string slice.
420 ///
421 /// ```
422 /// # use serde_yaml::Value;
423 /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
424 /// assert!(v.is_string());
425 /// ```
426 ///
427 /// ```
428 /// # use serde_yaml::Value;
429 /// let v: Value = serde_yaml::from_str("42").unwrap();
430 /// assert!(!v.is_string());
431 /// ```
is_string(&self) -> bool432 pub fn is_string(&self) -> bool {
433 self.as_str().is_some()
434 }
435
436 /// If the `Value` is a String, returns the associated str. Returns None
437 /// otherwise.
438 ///
439 /// ```
440 /// # use serde_yaml::Value;
441 /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
442 /// assert_eq!(v.as_str(), Some("lorem ipsum"));
443 /// ```
444 ///
445 /// ```
446 /// # use serde_yaml::Value;
447 /// let v: Value = serde_yaml::from_str("false").unwrap();
448 /// assert_eq!(v.as_str(), None);
449 /// ```
as_str(&self) -> Option<&str>450 pub fn as_str(&self) -> Option<&str> {
451 match *self {
452 Value::String(ref s) => Some(s),
453 _ => None,
454 }
455 }
456
457 /// Returns true if the `Value` is a sequence. Returns false otherwise.
458 ///
459 /// ```
460 /// # use serde_yaml::Value;
461 /// let v: Value = serde_yaml::from_str("[1, 2, 3]").unwrap();
462 /// assert!(v.is_sequence());
463 /// ```
464 ///
465 /// ```
466 /// # use serde_yaml::Value;
467 /// let v: Value = serde_yaml::from_str("true").unwrap();
468 /// assert!(!v.is_sequence());
469 /// ```
is_sequence(&self) -> bool470 pub fn is_sequence(&self) -> bool {
471 self.as_sequence().is_some()
472 }
473
474 /// If the `Value` is a sequence, return a reference to it if possible.
475 /// Returns None otherwise.
476 ///
477 /// ```
478 /// # use serde_yaml::{Value, Number};
479 /// let v: Value = serde_yaml::from_str("[1, 2]").unwrap();
480 /// assert_eq!(v.as_sequence(), Some(&vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]));
481 /// ```
482 ///
483 /// ```
484 /// # use serde_yaml::Value;
485 /// let v: Value = serde_yaml::from_str("false").unwrap();
486 /// assert_eq!(v.as_sequence(), None);
487 /// ```
as_sequence(&self) -> Option<&Sequence>488 pub fn as_sequence(&self) -> Option<&Sequence> {
489 match *self {
490 Value::Sequence(ref seq) => Some(seq),
491 _ => None,
492 }
493 }
494
495 /// If the `Value` is a sequence, return a mutable reference to it if
496 /// possible. Returns None otherwise.
497 ///
498 /// ```
499 /// # use serde_yaml::{Value, Number};
500 /// let mut v: Value = serde_yaml::from_str("[1]").unwrap();
501 /// let s = v.as_sequence_mut().unwrap();
502 /// s.push(Value::Number(Number::from(2)));
503 /// assert_eq!(s, &vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]);
504 /// ```
505 ///
506 /// ```
507 /// # use serde_yaml::Value;
508 /// let mut v: Value = serde_yaml::from_str("false").unwrap();
509 /// assert_eq!(v.as_sequence_mut(), None);
510 /// ```
as_sequence_mut(&mut self) -> Option<&mut Sequence>511 pub fn as_sequence_mut(&mut self) -> Option<&mut Sequence> {
512 match *self {
513 Value::Sequence(ref mut seq) => Some(seq),
514 _ => None,
515 }
516 }
517
518 /// Returns true if the `Value` is a mapping. Returns false otherwise.
519 ///
520 /// ```
521 /// # use serde_yaml::Value;
522 /// let v: Value = serde_yaml::from_str("a: 42").unwrap();
523 /// assert!(v.is_mapping());
524 /// ```
525 ///
526 /// ```
527 /// # use serde_yaml::Value;
528 /// let v: Value = serde_yaml::from_str("true").unwrap();
529 /// assert!(!v.is_mapping());
530 /// ```
is_mapping(&self) -> bool531 pub fn is_mapping(&self) -> bool {
532 self.as_mapping().is_some()
533 }
534
535 /// If the `Value` is a mapping, return a reference to it if possible.
536 /// Returns None otherwise.
537 ///
538 /// ```
539 /// # use serde_yaml::{Value, Mapping, Number};
540 /// let v: Value = serde_yaml::from_str("a: 42").unwrap();
541 ///
542 /// let mut expected = Mapping::new();
543 /// expected.insert(Value::String("a".into()),Value::Number(Number::from(42)));
544 ///
545 /// assert_eq!(v.as_mapping(), Some(&expected));
546 /// ```
547 ///
548 /// ```
549 /// # use serde_yaml::Value;
550 /// let v: Value = serde_yaml::from_str("false").unwrap();
551 /// assert_eq!(v.as_mapping(), None);
552 /// ```
as_mapping(&self) -> Option<&Mapping>553 pub fn as_mapping(&self) -> Option<&Mapping> {
554 match *self {
555 Value::Mapping(ref map) => Some(map),
556 _ => None,
557 }
558 }
559
560 /// If the `Value` is a mapping, return a reference to it if possible.
561 /// Returns None otherwise.
562 ///
563 /// ```
564 /// # use serde_yaml::{Value, Mapping, Number};
565 /// let mut v: Value = serde_yaml::from_str("a: 42").unwrap();
566 /// let m = v.as_mapping_mut().unwrap();
567 /// m.insert(Value::String("b".into()), Value::Number(Number::from(21)));
568 ///
569 /// let mut expected = Mapping::new();
570 /// expected.insert(Value::String("a".into()), Value::Number(Number::from(42)));
571 /// expected.insert(Value::String("b".into()), Value::Number(Number::from(21)));
572 ///
573 /// assert_eq!(m, &expected);
574 /// ```
575 ///
576 /// ```
577 /// # use serde_yaml::{Value, Mapping};
578 /// let mut v: Value = serde_yaml::from_str("false").unwrap();
579 /// assert_eq!(v.as_mapping_mut(), None);
580 /// ```
as_mapping_mut(&mut self) -> Option<&mut Mapping>581 pub fn as_mapping_mut(&mut self) -> Option<&mut Mapping> {
582 match *self {
583 Value::Mapping(ref mut map) => Some(map),
584 _ => None,
585 }
586 }
587 }
588
yaml_to_value(yaml: Yaml) -> Value589 fn yaml_to_value(yaml: Yaml) -> Value {
590 match yaml {
591 Yaml::Real(f) => {
592 if f == ".inf" {
593 Value::Number(f64::INFINITY.into())
594 } else if f == "-.inf" {
595 Value::Number(f64::NEG_INFINITY.into())
596 } else if f == ".nan" {
597 Value::Number(f64::NAN.into())
598 } else if let Ok(n) = u64::from_str(&f) {
599 Value::Number(n.into())
600 } else if let Ok(n) = i64::from_str(&f) {
601 Value::Number(n.into())
602 } else if let Ok(n) = f64::from_str(&f) {
603 Value::Number(n.into())
604 } else {
605 Value::String(f)
606 }
607 }
608 Yaml::Integer(i) => Value::Number(i.into()),
609 Yaml::String(s) => Value::String(s),
610 Yaml::Boolean(b) => Value::Bool(b),
611 Yaml::Array(sequence) => Value::Sequence(sequence.into_iter().map(yaml_to_value).collect()),
612 Yaml::Hash(hash) => Value::Mapping(
613 hash.into_iter()
614 .map(|(k, v)| (yaml_to_value(k), yaml_to_value(v)))
615 .collect(),
616 ),
617 Yaml::Alias(_) => panic!("alias unsupported"),
618 Yaml::Null => Value::Null,
619 Yaml::BadValue => panic!("bad value"),
620 }
621 }
622
623 impl Eq for Value {}
624
625 impl Hash for Value {
hash<H: Hasher>(&self, state: &mut H)626 fn hash<H: Hasher>(&self, state: &mut H) {
627 match *self {
628 Value::Null => 0.hash(state),
629 Value::Bool(b) => (1, b).hash(state),
630 Value::Number(ref i) => (2, i).hash(state),
631 Value::String(ref s) => (3, s).hash(state),
632 Value::Sequence(ref seq) => (4, seq).hash(state),
633 Value::Mapping(ref map) => (5, map).hash(state),
634 }
635 }
636 }
637
638 mod from;
639 mod index;
640 mod partial_eq;
641
642 mod de;
643 mod ser;
644