use zvt::{encoding, length, Tag, ZVTError, Zvt, ZvtSerializer, ZvtSerializerImpl}; #[test] #[rustfmt::skip] fn test_zvt_serializer_impl() { type Input = u16; // Test without length and tag. assert_eq!(::serialize_tagged(&12, None), [12, 0]); assert_eq!(::deserialize_tagged(&[12, 0], None).unwrap().0, 12); // Tests with length and custom encoding. assert_eq!(>::serialize_tagged(&12, None), [2, 12, 0]); assert_eq!(>::deserialize_tagged(&[2, 12, 0], None).unwrap().0, 12); assert_eq!(>::serialize_tagged(&12, None), [2, 12, 0]); assert_eq!(>::deserialize_tagged(&[2, 12, 0], None).unwrap().0, 12); assert_eq!(>::serialize_tagged(&12, None), [1, 0x12]); assert_eq!(>::deserialize_tagged(&[1, 0x12], None).unwrap().0, 12); // Test with length and tags. assert_eq!(::serialize_tagged(&12, Some(Tag(11))), [11, 12, 0]); assert_eq!(::deserialize_tagged(&[11, 12, 0], Some(Tag(11))).unwrap().0, 12); assert_eq!(>::serialize_tagged(&12, Some(Tag(11))), [11, 2, 12, 0]); assert_eq!(>::deserialize_tagged(&[11, 2, 12, 0], Some(Tag(11))).unwrap().0, 12); assert_eq!(>::serialize_tagged(&12, Some(Tag(11))), [0, 11, 2, 0, 12]); assert_eq!(>::deserialize_tagged(&[0, 11, 2, 0, 12], Some(Tag(11))).unwrap().0, 12); // Test failures assert_eq!(::deserialize_tagged(&[1], None), Err(ZVTError::IncompleteData)); assert_eq!(::deserialize_tagged(&[12, 12, 0], Some(Tag(11))), Err(ZVTError::WrongTag(Tag(12)))); } #[test] #[rustfmt::skip] fn test_zvt_serializer_impl_option() { // Tests the optional logic of the ZvtSerializerImpl. type Input = Option; // Test without a tag. assert_eq!(::serialize_tagged(&Some(12), None), [12, 0]); assert_eq!(::deserialize_tagged(&[12, 0], None).unwrap().0, Some(12)); assert_eq!(::serialize_tagged(&None, None), []); assert_eq!(::deserialize_tagged(&[0], None).unwrap().0, None); // Test with a tag. assert_eq!(::serialize_tagged(&Some(12), Some(Tag(11))), [11, 12, 0]); assert_eq!(::deserialize_tagged(&[11, 12, 0], Some(Tag(11))).unwrap().0, Some(12)); assert_eq!(::serialize_tagged(&None, Some(Tag(11))), []); assert_eq!(::deserialize_tagged(&[], Some(Tag(11))), Err(ZVTError::IncompleteData)); assert_eq!(::deserialize_tagged(&[0], Some(Tag(11))), Err(ZVTError::WrongTag(Tag(0)))); } #[test] fn test_command() { #[derive(Zvt, PartialEq, Debug)] #[zvt_control_field(class = 13, instr = 12)] struct Bar { a: u8, #[zvt_bmp(number = 0x3, encoding = encoding::BigEndian)] b: Option, #[zvt_bmp(number = 0x1)] c: u16, #[zvt_bmp(number = 0x2)] d: Option, } // Some legitimate values. let values = [ ( Bar { a: 1, b: Some(2), c: 3, d: None, }, vec![13, 12, 9, 1, 3, 0, 0, 0, 2, 1, 3, 0], ), ( Bar { a: 1, b: None, c: 3, d: Some(4), }, vec![13, 12, 9, 1, 1, 3, 0, 2, 4, 0, 0, 0], ), ]; for (input, bytes) in values { assert_eq!(input.zvt_serialize(), bytes); assert_eq!(Bar::zvt_deserialize(&bytes).unwrap().0, input); } // The tagged values but not in order. let values = [ vec![13, 12, 14, 1, 2, 4, 0, 0, 0, 1, 3, 0, 3, 0, 0, 0, 2], vec![13, 12, 14, 1, 2, 4, 0, 0, 0, 3, 0, 0, 0, 2, 1, 3, 0], ]; let expected = Bar { a: 1, b: Some(2), c: 3, d: Some(4), }; for bytes in values { assert_eq!(Bar::zvt_deserialize(&bytes).unwrap().0, expected); } // Missing required field c let bytes = vec![13, 12, 11, 1, 2, 4, 0, 0, 0, 3, 0, 0, 0, 2]; assert_eq!( Bar::zvt_deserialize(&bytes), Err(ZVTError::MissingRequiredTags(vec![Tag(0x1)])) ); // Duplicate field b let bytes = vec![13, 12, 14, 1, 3, 0, 0, 0, 2, 1, 3, 0, 3, 0, 0, 0, 2]; assert_eq!( Bar::zvt_deserialize(&bytes), Err(ZVTError::DuplicateTag(Tag(3))) ); } #[test] fn test_encodings() { #[derive(Zvt, Debug, PartialEq)] struct Foo { #[zvt_bmp(encoding = encoding::BigEndian)] a: u16, #[zvt_bmp(length = length::Tlv, encoding = encoding::Bcd)] b: u32, #[zvt_bmp(encoding = encoding::Hex)] c: String, } let input = Foo { a: 1, b: 2, c: "ffde".to_string(), }; let expected_bytes = vec![0, 1, 1, 2, 0xff, 0xde]; let bytes = input.zvt_serialize(); assert_eq!(bytes, expected_bytes); assert_eq!(Foo::zvt_deserialize(&expected_bytes).unwrap().0, input); } #[test] fn test_named_struct() { #[derive(Zvt, Debug, PartialEq)] struct MyNamedStruct { x: u8, y: u32, } let d = MyNamedStruct { x: 1, y: 2 }; let expected_bytes = vec![1, 2, 0, 0, 0]; assert_eq!(expected_bytes, d.zvt_serialize()); let deser = MyNamedStruct::zvt_deserialize(&expected_bytes).unwrap(); assert_eq!(deser.0, d); assert!(deser.1.is_empty()) } #[test] fn test_foo() { #[derive(Zvt, PartialEq, Debug)] struct Foo { #[zvt_bmp(length = length::Fixed<2>, encoding = encoding::Bcd)] a: usize, #[zvt_bmp(number = 0x13, length = length::Fixed<4>, encoding = encoding::Bcd)] b: Option, } let f = Foo { a: 1, b: None }; let bytes = f.zvt_serialize(); let o = Foo::zvt_deserialize(bytes.as_slice()).unwrap(); assert_eq!(f, o.0); } #[test] fn test_nested() { #[derive(Zvt, PartialEq, Debug)] struct Inner { a: u8, #[zvt_bmp(number = 0x12)] b: Option, } #[derive(Zvt, PartialEq, Debug)] struct Outer { a: u16, #[zvt_bmp(number = 0x12, length = length::Tlv)] b: Option, } let f = Outer { a: 1, b: Some(Inner { a: 2, b: Some(3) }), }; let bytes = f.zvt_serialize(); let o = Outer::zvt_deserialize(bytes.as_slice()).unwrap(); assert_eq!(f, o.0); } #[test] fn test_tagged_but_optional_but_still_tagged() { #[derive(Zvt, PartialEq, Debug)] struct Foo { #[zvt_bmp(number = 0x11)] a: u16, #[zvt_bmp(number = 0x12)] b: Option, } // The simple case for f in [Foo { a: 1, b: Some(2) }, Foo { a: 1, b: None }] { let bytes = f.zvt_serialize(); let o = Foo::zvt_deserialize(bytes.as_slice()).unwrap(); assert_eq!(f, o.0); } // Now check the case where the required field is missing. for data in [vec![], vec![0x12, 0, 0]] { assert_eq!( Foo::zvt_deserialize(&data), Err(ZVTError::MissingRequiredTags(vec![Tag(0x11)])) ); } }