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