diff --git a/README.md b/README.md index 32c70971..7992858c 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,12 @@ serde_yml = "0.0.10" Release notes are available under [GitHub releases][04]. -## Using Serde YAML +## Using Serde YML [API documentation is available in rustdoc form][docs.rs] but the general idea is: -[docs.rs]: https://docs.rs/serde_yaml +[docs.rs]: https://docs.rs/serde_yml ```rust use serde::{Serialize, Deserialize}; diff --git a/examples/value/de_examples.rs b/examples/value/de_examples.rs new file mode 100644 index 00000000..7c5a10b5 --- /dev/null +++ b/examples/value/de_examples.rs @@ -0,0 +1,115 @@ +//! This file demonstrates the deserialization of various data structures such as empty tuples, +//! empty tuple structs, newtype variants, sequences, maps, option types, and enums with multiple variants using `serde_yml`. + +use serde::Deserialize; +use serde_yml::Value; + +pub(crate) fn main() { + // Print a message to indicate the file being executed. + println!("\n❯ Executing examples/de_examples.rs"); + + // Example: Deserializing an empty tuple struct. + fn example_deserialize_empty_tuple_struct() { + let yaml_str = "---"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + #[derive(Deserialize, PartialEq, Debug)] + struct Empty; + + let result: Empty = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized Empty tuple struct: {:?}", result); + } + + // Example: Deserializing an empty tuple. + fn example_deserialize_empty_tuple() { + let yaml_str = "---"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + let result: () = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized Empty tuple: {:?}", result); + } + + // Example: Deserializing a newtype variant. + fn example_deserialize_newtype_variant() { + let yaml_str = "!Variant 0"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(i32), + } + + let result: E = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized newtype variant: {:?}", result); + } + + // Example: Deserializing a struct with multiple fields. + fn example_deserialize_struct_with_fields() { + let yaml_str = " +name: \"John Doe\" +age: 30 +"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + #[derive(Deserialize, PartialEq, Debug)] + struct Person { + name: String, + age: i32, + } + + let result: Person = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized struct with fields: {:?}", result); + } + + // Example: Deserializing a sequence (Vec). + fn example_deserialize_sequence() { + let yaml_str = " +- 1 +- 2 +- 3 +"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + let result: Vec = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized sequence: {:?}", result); + } + + // Example: Deserializing a map (HashMap). + fn example_deserialize_map() { + use std::collections::HashMap; + let yaml_str = " +key1: value1 +key2: value2 +"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + let result: HashMap = + serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized map: {:?}", result); + } + + // Example: Deserializing an option type. + fn example_deserialize_option() { + let yaml_str_some = "some_value"; + let value_some: Value = + serde_yml::from_str(yaml_str_some).unwrap(); + let result_some: Option = + serde_yml::from_value(value_some).unwrap(); + println!("\n✅ Deserialized option (Some): {:?}", result_some); + + let yaml_str_none = "---"; + let value_none: Value = + serde_yml::from_str(yaml_str_none).unwrap(); + let result_none: Option = + serde_yml::from_value(value_none).unwrap(); + println!("\n✅ Deserialized option (None): {:?}", result_none); + } + // Execute the examples + example_deserialize_empty_tuple_struct(); + example_deserialize_empty_tuple(); + example_deserialize_newtype_variant(); + example_deserialize_struct_with_fields(); + example_deserialize_sequence(); + example_deserialize_map(); + example_deserialize_option(); +} diff --git a/examples/value/mod.rs b/examples/value/mod.rs index 08a87737..780763b1 100644 --- a/examples/value/mod.rs +++ b/examples/value/mod.rs @@ -1,8 +1,14 @@ +/// This module contains the `de` examples. +pub(crate) mod de_examples; + /// This module contains the `index` examples. pub(crate) mod index_examples; /// The main function that runs all the example modules. pub(crate) fn main() { + // Run the example module `de_examples`. + de_examples::main(); + // Run the example module `index_examples`. index_examples::main(); } diff --git a/src/value/de.rs b/src/value/de.rs index 2c4d2ad0..a61ffb64 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -14,6 +14,7 @@ use std::fmt::Result as FmtResult; use std::slice; use std::vec; +/// Deserializes a `Value` from a given deserializer. impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result where @@ -31,46 +32,46 @@ impl<'de> Deserialize<'de> for Value { formatter.write_str("any YAML value") } - fn visit_bool(self, b: bool) -> Result + fn visit_bool(self, value: bool) -> Result where E: de::Error, { - Ok(Value::Bool(b)) + Ok(Value::Bool(value)) } - fn visit_i64(self, i: i64) -> Result + fn visit_i64(self, value: i64) -> Result where E: de::Error, { - Ok(Value::Number(i.into())) + Ok(Value::Number(value.into())) } - fn visit_u64(self, u: u64) -> Result + fn visit_u64(self, value: u64) -> Result where E: de::Error, { - Ok(Value::Number(u.into())) + Ok(Value::Number(value.into())) } - fn visit_f64(self, f: f64) -> Result + fn visit_f64(self, value: f64) -> Result where E: de::Error, { - Ok(Value::Number(f.into())) + Ok(Value::Number(value.into())) } - fn visit_str(self, s: &str) -> Result + fn visit_str(self, value: &str) -> Result where E: de::Error, { - Ok(Value::String(s.to_owned())) + Ok(Value::String(value.to_owned())) } - fn visit_string(self, s: String) -> Result + fn visit_string(self, value: String) -> Result where E: de::Error, { - Ok(Value::String(s)) + Ok(Value::String(value)) } fn visit_unit(self) -> Result @@ -97,20 +98,20 @@ impl<'de> Deserialize<'de> for Value { Deserialize::deserialize(deserializer) } - fn visit_seq(self, data: A) -> Result + fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, { - let de = SeqAccessDeserializer::new(data); + let de = SeqAccessDeserializer::new(seq); let sequence = Sequence::deserialize(de)?; Ok(Value::Sequence(sequence)) } - fn visit_map(self, data: A) -> Result + fn visit_map(self, map: A) -> Result where A: MapAccess<'de>, { - let de = MapAccessDeserializer::new(data); + let de = MapAccessDeserializer::new(map); let mapping = Mapping::deserialize(de)?; Ok(Value::Mapping(mapping)) } @@ -134,6 +135,7 @@ impl<'de> Deserialize<'de> for Value { } impl Value { + /// Deserializes a number from the given `Value`. fn deserialize_number<'de, V>( &self, visitor: V, @@ -148,6 +150,7 @@ impl Value { } } +/// Visits a `Sequence` value with the given `Visitor`. fn visit_sequence<'de, V>( sequence: Sequence, visitor: V, @@ -166,6 +169,7 @@ where } } +/// Visits a borrowed `Sequence` value with the given `Visitor`. fn visit_sequence_ref<'de, V>( sequence: &'de Sequence, visitor: V, @@ -184,6 +188,7 @@ where } } +/// Visits a `Mapping` value with the given `Visitor`. fn visit_mapping<'de, V>( mapping: Mapping, visitor: V, @@ -202,6 +207,7 @@ where } } +/// Visits a borrowed `Mapping` value with the given `Visitor`. fn visit_mapping_ref<'de, V>( mapping: &'de Mapping, visitor: V, @@ -538,6 +544,7 @@ impl<'de> Deserializer<'de> for Value { } } +/// Represents an enum deserializer. struct EnumDeserializer<'a> { tag: &'a str, value: Option, @@ -561,6 +568,7 @@ impl<'de> EnumAccess<'de> for EnumDeserializer<'_> { } } +/// Represents a variant deserializer. struct VariantDeserializer { value: Option, } @@ -623,11 +631,13 @@ impl<'de> VariantAccess<'de> for VariantDeserializer { } } +/// Represents a sequence deserializer. pub(crate) struct SeqDeserializer { iter: vec::IntoIter, } impl SeqDeserializer { + /// Creates a new `SeqDeserializer` from the given vector of `Value`s. pub(crate) fn new(vec: Vec) -> Self { SeqDeserializer { iter: vec.into_iter(), @@ -705,12 +715,14 @@ impl<'de> SeqAccess<'de> for SeqDeserializer { } } +/// Represents a map deserializer. pub(crate) struct MapDeserializer { iter: ::IntoIter, value: Option, } impl MapDeserializer { + /// Creates a new `MapDeserializer` from the given `Mapping`. pub(crate) fn new(map: Mapping) -> Self { MapDeserializer { iter: map.into_iter(), @@ -984,7 +996,6 @@ impl<'de> Deserializer<'de> for &'de Value { { self.deserialize_unit(visitor) } - fn deserialize_newtype_struct( self, _name: &'static str, @@ -1104,16 +1115,14 @@ impl<'de> Deserializer<'de> for &'de Value { visitor.visit_unit() } } - +/// Represents an enum deserializer for borrowed values. struct EnumRefDeserializer<'de> { tag: &'de str, value: Option<&'de Value>, } - impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> { type Error = Error; type Variant = VariantRefDeserializer<'de>; - fn variant_seed( self, seed: V, @@ -1127,14 +1136,12 @@ impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> { Ok((variant, visitor)) } } - +/// Represents a variant deserializer for borrowed values. struct VariantRefDeserializer<'de> { value: Option<&'de Value>, } - impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { type Error = Error; - fn unit_variant(self) -> Result<(), Error> { match self.value { Some(value) => { @@ -1194,20 +1201,18 @@ impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { } } } - +/// Represents a sequence deserializer for borrowed values. pub(crate) struct SeqRefDeserializer<'de> { iter: slice::Iter<'de, Value>, } - impl<'de> SeqRefDeserializer<'de> { + /// Creates a new SeqRefDeserializer from the given slice of Values. pub(crate) fn new(slice: &'de [Value]) -> Self { SeqRefDeserializer { iter: slice.iter() } } } - impl<'de> Deserializer<'de> for SeqRefDeserializer<'de> { type Error = Error; - #[inline] fn deserialize_any( mut self, @@ -1249,10 +1254,8 @@ impl<'de> Deserializer<'de> for SeqRefDeserializer<'de> { map struct enum identifier } } - impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { type Error = Error; - fn next_element_seed( &mut self, seed: T, @@ -1273,13 +1276,13 @@ impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { } } } - +/// Represents a map deserializer for borrowed values. pub(crate) struct MapRefDeserializer<'de> { iter: Option<<&'de Mapping as IntoIterator>::IntoIter>, value: Option<&'de Value>, } - impl<'de> MapRefDeserializer<'de> { + /// Creates a new MapRefDeserializer from the given Mapping. pub(crate) fn new(map: &'de Mapping) -> Self { MapRefDeserializer { iter: Some(map.iter()), @@ -1287,10 +1290,8 @@ impl<'de> MapRefDeserializer<'de> { } } } - impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { type Error = Error; - fn next_key_seed( &mut self, seed: T, @@ -1324,10 +1325,8 @@ impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { } } } - impl<'de> Deserializer<'de> for MapRefDeserializer<'de> { type Error = Error; - #[inline] fn deserialize_any(self, visitor: V) -> Result where @@ -1352,8 +1351,8 @@ impl<'de> Deserializer<'de> for MapRefDeserializer<'de> { map struct enum identifier } } - impl Value { + /// Returns an error indicating that the value is of an invalid type for the given visitor. #[cold] fn invalid_type(&self, exp: &dyn Expected) -> E where @@ -1361,7 +1360,7 @@ impl Value { { de::Error::invalid_type(self.unexpected(), exp) } - + /// Returns an `Unexpected` instance for the current `Value`. #[cold] pub(crate) fn unexpected(&self) -> Unexpected<'_> { match self { diff --git a/tests/value/mod.rs b/tests/value/mod.rs index f169c813..c9f35328 100644 --- a/tests/value/mod.rs +++ b/tests/value/mod.rs @@ -1,3 +1,6 @@ +/// The `test_de` module contains tests for the `Deserialize` trait implementations. +pub mod test_de; + /// The `test_debug` module contains tests for the `Debug` trait implementations. pub mod test_debug; diff --git a/tests/value/test_de.rs b/tests/value/test_de.rs new file mode 100644 index 00000000..47a78917 --- /dev/null +++ b/tests/value/test_de.rs @@ -0,0 +1,495 @@ +#[cfg(test)] +mod tests { + use serde::Deserialize; + use serde_yml::value::{Tag, TaggedValue, Value}; + + /// Test deserialization of a `null` value into `Option<()>`. + #[test] + fn test_deserialize_null() { + let value = Value::Null; + let result: Option<()> = serde_yml::from_value(value).unwrap(); + assert_eq!(result, None); + } + + /// Test deserialization of a `bool` value. + #[test] + fn test_deserialize_bool() { + let value = Value::Bool(true); + let result: bool = serde_yml::from_value(value).unwrap(); + assert!(result); + } + + /// Test deserialization of an `i64` value. + #[test] + fn test_deserialize_i64() { + let value = Value::Number(42.into()); + let result: i64 = serde_yml::from_value(value).unwrap(); + assert_eq!(result, 42); + } + + /// Test deserialization of a `u64` value. + #[test] + fn test_deserialize_u64() { + let value = Value::Number(42.into()); + let result: u64 = serde_yml::from_value(value).unwrap(); + assert_eq!(result, 42); + } + + /// Test deserialization of a `f64` value. + #[test] + fn test_deserialize_f64() { + let value = Value::Number(42.5.into()); + let result: f64 = serde_yml::from_value(value).unwrap(); + assert_eq!(result, 42.5); + } + + /// Test deserialization of a `String` value. + #[test] + fn test_deserialize_string() { + let value = Value::String("hello".to_string()); + let result: String = serde_yml::from_value(value).unwrap(); + assert_eq!(result, "hello"); + } + + /// Test deserialization of a sequence into a `Vec`. + #[test] + fn test_deserialize_sequence() { + let value = Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + ]); + let result: Vec = serde_yml::from_value(value).unwrap(); + assert_eq!(result, vec![1, 2]); + } + + /// Test deserialization of a tagged enum variant. + #[test] + fn test_deserialize_enum() { + let value = Value::Tagged(Box::new(TaggedValue { + tag: Tag::new("B"), + value: Value::Number(42.into()), + })); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + A, + B(i32), + C { x: i32 }, + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::B(42)); + } + + /// Test deserialization of a newtype struct. + #[test] + fn test_deserialize_newtype_struct() { + let value = Value::Number(42.into()); + #[derive(Deserialize, PartialEq, Debug)] + struct Newtype(i32); + let result: Newtype = serde_yml::from_value(value).unwrap(); + assert_eq!(result, Newtype(42)); + } + + /// Test deserialization of a tuple. + #[test] + fn test_deserialize_tuple() { + let value = Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + ]); + let result: (i32, i32) = serde_yml::from_value(value).unwrap(); + assert_eq!(result, (1, 2)); + } + + /// Test deserialization of a tuple struct. + #[test] + fn test_deserialize_tuple_struct() { + let value = Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + ]); + #[derive(Deserialize, PartialEq, Debug)] + struct TupleStruct(i32, i32); + let result: TupleStruct = serde_yml::from_value(value).unwrap(); + assert_eq!(result, TupleStruct(1, 2)); + } + + /// Test deserialization of a sequence into a `Vec`. + #[test] + fn test_deserialize_bytes() { + let value = Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + ]); + let result: Vec = serde_yml::from_value(value).unwrap(); + assert_eq!(result, vec![1, 2]); + } + + /// Test deserialization of an identifier (string). + #[test] + fn test_deserialize_identifier() { + let value = Value::String("hello".to_string()); + let result: String = serde_yml::from_value(value).unwrap(); + assert_eq!(result, "hello"); + } + + /// Test deserialization of a struct. + #[test] + fn test_deserialize_struct() { + let value = Value::Mapping( + vec![ + ( + Value::String("x".to_string()), + Value::Number(1.into()), + ), + ( + Value::String("y".to_string()), + Value::Number(2.into()), + ), + ] + .into_iter() + .collect(), + ); + #[derive(Deserialize, PartialEq, Debug)] + struct Point { + x: i32, + y: i32, + } + let result: Point = serde_yml::from_value(value).unwrap(); + assert_eq!(result, Point { x: 1, y: 2 }); + } + + /// Test deserialization of a map. + #[test] + fn test_deserialize_map() { + let value = Value::Mapping( + vec![ + ( + Value::String("x".to_string()), + Value::Number(1.into()), + ), + ( + Value::String("y".to_string()), + Value::Number(2.into()), + ), + ] + .into_iter() + .collect(), + ); + let result: std::collections::HashMap = + serde_yml::from_value(value).unwrap(); + let mut expected = std::collections::HashMap::new(); + expected.insert("x".to_string(), 1); + expected.insert("y".to_string(), 2); + assert_eq!(result, expected); + } + + /// Test deserialization of `Option` with `Some` value. + #[test] + fn test_deserialize_option_some() { + let value = Value::Number(42.into()); + let result: Option = serde_yml::from_value(value).unwrap(); + assert_eq!(result, Some(42)); + } + + /// Test deserialization of `Option` with `None` value. + #[test] + fn test_deserialize_option_none() { + let value = Value::Null; + let result: Option = serde_yml::from_value(value).unwrap(); + assert_eq!(result, None); + } + + /// Test deserialization of a `char` value. + #[test] + fn test_deserialize_char() { + let value = Value::String("a".to_string()); + let result: char = serde_yml::from_value(value).unwrap(); + assert_eq!(result, 'a'); + } + + /// Test deserialization of a unit value. + #[test] + fn test_deserialize_unit() { + let value = Value::Null; + let result: () = serde_yml::from_value(value).unwrap(); + println!( + "✅ Deserialized unit value successfully. {:?}", + result + ); + } + /// Test deserialization of a unit struct. + #[test] + fn test_deserialize_unit_struct() { + let value = Value::Null; + #[derive(Deserialize, PartialEq, Debug)] + struct Unit; + let result: Unit = serde_yml::from_value(value).unwrap(); + assert_eq!(result, Unit); + } + /// Test deserialization of an empty tuple struct. + #[test] + fn test_deserialize_empty_tuple_struct() { + let yaml_str = "---"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + #[derive(Deserialize, PartialEq, Debug)] + struct Empty; + + let result: Empty = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized Empty tuple struct: {:?}", result); + } + + /// Test deserialization of an empty tuple. + #[test] + fn test_deserialize_empty_tuple() { + let yaml_str = "---"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + let result: () = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized Empty tuple: {:?}", result); + } + + /// Test deserialization of an empty struct. + #[test] + fn test_deserialize_empty_struct() { + let value = Value::Null; + #[derive(Deserialize, PartialEq, Debug)] + struct Empty; + let result: Empty = serde_yml::from_value(value).unwrap(); + assert_eq!(result, Empty); + } + /// Test deserialization of a unit variant. + #[test] + fn test_deserialize_unit_variant() { + let value = Value::String("Variant".to_string()); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant, + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant); + } + /// Test deserialization of a newtype variant. + #[test] + fn test_deserialize_newtype_variant() { + let yaml_str = "!Variant 0"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(i32), + } + + let result: E = serde_yml::from_value(value).unwrap(); + println!("\n✅ Deserialized newtype variant: {:?}", result); + } + + /// Test deserialization of a tuple variant. + #[test] + fn test_deserialize_tuple_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\n- 1\n- 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(i32, i32), + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant(1, 2)); + } + + /// Test deserialization of a struct variant. + #[test] + fn test_deserialize_struct_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\nx: 1\ny: 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant { x: i32, y: i32 }, + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant { x: 1, y: 2 }); + } + /// Test deserialization of a sequence variant. + #[test] + fn test_deserialize_sequence_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\n- 1\n- 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(Vec), + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant(vec![1, 2])); + } + /// Test deserialization of a map variant. + #[test] + fn test_deserialize_map_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\nx: 1\ny: 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(std::collections::HashMap), + } + let result: E = serde_yml::from_value(value).unwrap(); + let mut expected = std::collections::HashMap::new(); + expected.insert("x".to_string(), 1); + expected.insert("y".to_string(), 2); + assert_eq!(result, E::Variant(expected)); + } + /// Test deserialization of a tagged unit variant. + #[test] + fn test_deserialize_tagged_unit_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant, + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant); + } + /// Test deserialization of a tagged newtype variant. + #[test] + fn test_deserialize_tagged_newtype_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant 0\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(i32), + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant(0)); + } + /// Test deserialization of a tagged tuple variant. + #[test] + fn test_deserialize_tagged_tuple_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\n- 1\n- 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(i32, i32), + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant(1, 2)); + } + /// Test deserialization of a tagged struct variant. + #[test] + fn test_deserialize_tagged_struct_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\nx: 1\ny: 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant { x: i32, y: i32 }, + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant { x: 1, y: 2 }); + } + /// Test deserialization of a tagged sequence variant. + #[test] + fn test_deserialize_tagged_sequence_variant() { + // YAML representation of the enum variant + let yaml_str = "---\n!Variant\n- 1\n- 2\n"; + let value: Value = serde_yml::from_str(yaml_str).unwrap(); + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Variant(Vec), + } + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::Variant(vec![1, 2])); + } + /// Test deserialization of a `f32` value. + #[test] + fn test_deserialize_f32() { + let value = Value::Number(serde_yml::Number::from(42.5f32)); + let result: f32 = serde_yml::from_value(value).unwrap(); + assert_eq!(result, 42.5f32); + } + /// Test deserialization of a `()` value. + #[test] + fn test_deserialize_unit_value() { + let value = Value::Null; + let result: () = serde_yml::from_value(value).unwrap(); + println!( + "✅ Deserialized unit value successfully. {:?}", + result + ); + } + + /// Test deserialization of a byte array. + #[test] + fn test_deserialize_byte_array() { + let value = Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + Value::Number(3.into()), + ]); + let result: [u8; 3] = serde_yml::from_value(value).unwrap(); + assert_eq!(result, [1, 2, 3]); + } + + /// Test deserialization of an optional byte array. + #[test] + fn test_deserialize_optional_byte_array() { + let value = Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + Value::Number(3.into()), + ]); + let result: Option<[u8; 3]> = + serde_yml::from_value(value).unwrap(); + assert_eq!(result, Some([1, 2, 3])); + } + + /// Test deserialization of a unit struct variant. + #[test] + fn test_deserialize_unit_struct_variant() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + V, + } + let value = Value::String("V".to_string()); + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::V); + } + + /// Test deserialization of a newtype struct variant. + #[test] + fn test_deserialize_newtype_struct_variant() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + V(i32), + } + let value = Value::Tagged(Box::new(TaggedValue { + tag: Tag::new("V"), + value: Value::Number(42.into()), + })); + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::V(42)); + } + + /// Test deserialization of a tuple struct variant. + #[test] + fn test_deserialize_tuple_struct_variant() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + V(i32, i32), + } + let value = Value::Tagged(Box::new(TaggedValue { + tag: Tag::new("V"), + value: Value::Sequence(vec![ + Value::Number(1.into()), + Value::Number(2.into()), + ]), + })); + let result: E = serde_yml::from_value(value).unwrap(); + assert_eq!(result, E::V(1, 2)); + } +}