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