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