#![doc = concat!( include_str!("../README.md"), "# What is Preserves?\n\n", include_str!("../doc/what-is-preserves.md"), )] pub mod de; pub mod error; pub mod hex; pub mod ser; pub mod set; pub mod symbol; pub mod value; #[cfg(test)] mod dom { use super::value::*; use std::io; #[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)] pub enum Dom { One, Two, } impl Domain for Dom {} impl std::str::FromStr for Dom { type Err = io::Error; fn from_str(s: &str) -> Result { match s { "One" => Ok(Dom::One), "Two" => Ok(Dom::Two), _ => Err(io::Error::new( io::ErrorKind::Other, "cannot parse preserves test domain", )), } } } fn dom_as_preserves(v: &Dom) -> io::Result { Ok(match v { Dom::One => Value::bytestring(vec![255, 255, 255, 255]), Dom::Two => Value::symbol(&format!("Dom::{:?}", v)), }) } #[test] fn test_one() { let v: PlainValue<_> = Value::from(vec![ Value::from(1).wrap(), Value::Embedded(Dom::One).wrap(), Value::from(2).wrap(), ]) .wrap(); assert_eq!( PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(), [0xb5, 0xb0, 0x01, 0x01, 0xb2, 0x04, 255, 255, 255, 255, 0xb0, 0x01, 0x02, 0x84] ); } #[test] fn test_two() { let v: PlainValue<_> = Value::from(vec![ Value::from(1).wrap(), Value::Embedded(Dom::Two).wrap(), Value::from(2).wrap(), ]) .wrap(); assert_eq!( PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(), [0xb5, 0xb0, 0x01, 0x01, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0xb0, 0x01, 0x02, 0x84] ); } } #[cfg(test)] mod ieee754_section_5_10_total_order_tests { use super::dom::Dom; use std::cmp::Ordering::{Equal, Greater, Less}; use crate::value::{PlainValue, Value}; fn d(val: f64) -> Value> { Value::from(val) } // TODO: Test cases with a few different signalling and non-signalling NaNs #[test] fn case64_a_1() { assert_eq!(d(1.0).cmp(&d(2.0)), Less) } #[test] fn case64_a_2() { assert_eq!(d(-1.0).cmp(&d(1.0)), Less) } #[test] fn case64_a_3() { assert_eq!(d(0.0).cmp(&d(1.0)), Less) } #[test] fn case64_a_4() { assert_eq!(d(-1.0).cmp(&d(0.0)), Less) } #[test] fn case64_a_5() { assert_eq!(d(-1e32).cmp(&d(-1e31)), Less) } #[test] fn case64_a_6() { assert_eq!(d(-1e32).cmp(&d(1e33)), Less) } #[test] fn case64_a_7() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_a_8() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(0.0)), Less) } #[test] fn case64_a_9() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(1.0)), Less) } #[test] fn case64_a_10() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(1e33)), Less) } #[test] fn case64_a_11() { assert_eq!(d(0.0).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_a_12() { assert_eq!(d(1.0).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_a_13() { assert_eq!(d(1e33).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_b_1() { assert_eq!(d(2.0).cmp(&d(1.0)), Greater) } #[test] fn case64_b_2() { assert_eq!(d(1.0).cmp(&d(-1.0)), Greater) } #[test] fn case64_b_3() { assert_eq!(d(1.0).cmp(&d(0.0)), Greater) } #[test] fn case64_b_4() { assert_eq!(d(0.0).cmp(&d(-1.0)), Greater) } #[test] fn case64_b_5() { assert_eq!(d(-1e31).cmp(&d(-1e32)), Greater) } #[test] fn case64_b_6() { assert_eq!(d(1e33).cmp(&d(-1e32)), Greater) } #[test] fn case64_b_7() { assert_eq!( d(std::f64::INFINITY).cmp(&d(std::f64::NEG_INFINITY)), Greater ) } #[test] fn case64_b_8() { assert_eq!(d(std::f64::INFINITY).cmp(&d(0.0)), Greater) } #[test] fn case64_b_9() { assert_eq!(d(std::f64::INFINITY).cmp(&d(1.0)), Greater) } #[test] fn case64_b_10() { assert_eq!(d(std::f64::INFINITY).cmp(&d(1e33)), Greater) } #[test] fn case64_b_11() { assert_eq!(d(0.0).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_b_12() { assert_eq!(d(1.0).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_b_13() { assert_eq!(d(1e33).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_c1() { assert_eq!(d(-0.0).cmp(&d(0.0)), Less) } #[test] fn case64_c2() { assert_eq!(d(0.0).cmp(&d(-0.0)), Greater) } #[test] fn case64_c3_1() { assert_eq!(d(-0.0).cmp(&d(-0.0)), Equal) } #[test] fn case64_c3_2() { assert_eq!(d(0.0).cmp(&d(0.0)), Equal) } #[test] fn case64_c3_3() { assert_eq!(d(1.0).cmp(&d(1.0)), Equal) } #[test] fn case64_c3_4() { assert_eq!(d(-1.0).cmp(&d(-1.0)), Equal) } #[test] fn case64_c3_5() { assert_eq!(d(-1e32).cmp(&d(-1e32)), Equal) } #[test] fn case64_c3_6() { assert_eq!(d(1e33).cmp(&d(1e33)), Equal) } } #[cfg(test)] mod value_tests { use super::dom::Dom; use crate::value::{repr::Record, signed_integer::SignedInteger, PlainValue, Value}; type VV = Value>; #[test] fn boolean_mut() { let mut b = VV::Boolean(true); assert!(b.is_boolean()); *(b.as_boolean_mut().unwrap()) = false; assert_eq!(b, VV::Boolean(false)); } #[test] fn double_mut() { let mut f = VV::from(1.0); assert!(f.is_f64()); *(f.as_f64_mut().unwrap()) = 123.45; assert_eq!(f, VV::from(123.45)); assert_eq!( (f.as_f64().unwrap() - 123.45).abs() < std::f64::EPSILON, true ); } #[test] fn signedinteger_mut() { let mut i = VV::from(123); assert!(i.is_signedinteger()); *(i.as_signedinteger_mut().unwrap()) = SignedInteger::from(234i128); assert_eq!(i, VV::from(234)); assert_eq!(i.as_i().unwrap(), 234); } #[test] fn string_mut() { let mut s = VV::from("hello, world!"); assert!(s.is_string()); s.as_string_mut().unwrap().replace_range(7..12, "there"); assert_eq!(s, VV::from("hello, there!")); } #[test] fn bytes_mut() { let mut b = VV::from(&b"hello, world!"[..]); assert!(b.is_bytestring()); b.as_bytestring_mut() .unwrap() .splice(7..12, Vec::from(&b"there"[..])); assert_eq!(b, VV::from(&b"hello, there!"[..])); } #[test] fn symbol_mut() { let mut s = VV::symbol("abcd"); assert!(s.is_symbol()); s.as_symbol_mut().unwrap().replace_range(..2, "AB"); assert_eq!(s, VV::symbol("ABcd")); } #[test] fn record_mut() { let says = VV::symbol("says").wrap(); let mut r = VV::Record(Record(vec![ says.clone(), VV::from("Tony").wrap(), VV::from("Hello!").wrap(), ])); assert_eq!(r.as_record_mut(Some(0)), None); assert_eq!(r.as_record_mut(Some(1)), None); assert!(r.as_record_mut(Some(2)).is_some()); assert_eq!(r.as_record_mut(Some(3)), None); r.as_record_mut(None).unwrap().fields_mut()[0] = VV::from("Alice").wrap(); assert_eq!( r, VV::Record(Record(vec![ says, VV::from("Alice").wrap(), VV::from("Hello!").wrap() ])) ); } #[test] fn sequence_mut() { let mut s = VV::Sequence(vec![ VV::from(1).wrap(), VV::from(2).wrap(), VV::from(3).wrap(), ]); let r = VV::Sequence(vec![ VV::from(1).wrap(), VV::from(99).wrap(), VV::from(3).wrap(), ]); s.as_sequence_mut().unwrap()[1] = VV::from(99).wrap(); assert_eq!(r, s); } } #[cfg(test)] mod decoder_tests { use crate::de::from_bytes; use crate::error::{is_eof_io_error, Error, ExpectedKind}; use crate::value::{BinarySource, BytesBinarySource, ConfiguredReader, NestedValue, Value}; fn expect_number_out_of_range(r: Result) { match r { Ok(v) => panic!("Expected NumberOutOfRange, but got a parse of {:?}", v), Err(Error::NumberOutOfRange(_)) => (), Err(e) => panic!("Expected NumberOutOfRange, but got an error of {:?}", e), } } fn expect_expected(k: ExpectedKind, r: Result) { match r { Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v), Err(Error::Expected(k1, _)) if k1 == k => (), Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e), } } #[test] fn skip_annotations_noskip() { let buf = &b"\x85\xB0\x01\x02\xB0\x01\x01"[..]; let mut src = BytesBinarySource::new(&buf); let mut d = ConfiguredReader::new(src.packed_iovalues()); let v = d.demand_next().unwrap(); assert_eq!(v.annotations().slice().len(), 1); assert_eq!(v.annotations().slice()[0], Value::from(2).wrap()); assert_eq!(v.value(), &Value::from(1)); } #[test] fn skip_annotations_skip() { let buf = &b"\x85\xB0\x01\x02\xB0\x01\x01"[..]; let mut src = BytesBinarySource::new(&buf); let mut d = ConfiguredReader::new(src.packed_iovalues()); d.set_read_annotations(false); let v = d.demand_next().unwrap(); assert_eq!(v.annotations().slice().len(), 0); assert_eq!(v.value(), &Value::from(1)); } #[test] fn multiple_values_buf_advanced() { let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..]; assert_eq!(buf.len(), 16); let mut src = BytesBinarySource::new(&buf); let mut d = ConfiguredReader::new(src.packed_iovalues()); assert_eq!(d.reader.source.index, 0); assert_eq!( d.demand_next().unwrap().value(), &Value::simple_record0("Ping") ); assert_eq!(d.reader.source.index, 8); assert_eq!( d.demand_next().unwrap().value(), &Value::simple_record0("Pong") ); assert_eq!(d.reader.source.index, 16); assert!(d.next().is_none()); assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false }); } #[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::(b"\xB0\x01\x01").unwrap(), 1) } #[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::(b"\xB0\x00").unwrap(), 0) } #[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::(b"\xB0\x01\xff").unwrap(), -1) } #[test] fn direct_i8_format_b() { assert_eq!(from_bytes::(b"\xb0\x01\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::(b"\xb0\x03\xff\xff\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b_much_too_long() { assert_eq!( from_bytes::(b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2 ) } #[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::(b"\xB0\x01\x01").unwrap(), 1) } #[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::(b"\xB0\x00").unwrap(), 0) } #[test] fn direct_u8_format_b() { assert_eq!(from_bytes::(b"\xb0\x011").unwrap(), 49) } #[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::(b"\xb0\x04\0\0\01").unwrap(), 49) } #[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::(b"\xb0\x0a\0\0\0\0\0\0\0\0\01").unwrap(), 49) } #[test] fn direct_i16_format_a() { assert_eq!(from_bytes::(b"\xB0\x01\xfe").unwrap(), -2) } #[test] fn direct_i16_format_b() { assert_eq!(from_bytes::(b"\xb0\x02\xfe\xff").unwrap(), -257) } #[test] fn direct_u8_wrong_format() { expect_expected( ExpectedKind::SignedInteger, from_bytes::(b"\xb1\x05bogus"), ) } #[test] fn direct_u8_format_b_too_large() { expect_number_out_of_range(from_bytes::(b"\xb0\x04\0\011")) } #[test] fn direct_i8_format_b_too_large() { expect_number_out_of_range(from_bytes::(b"\xb0\x02\xfe\xff")) } #[test] fn direct_i16_format_b_too_large() { expect_number_out_of_range(from_bytes::(b"\xb0\x03\xfe\xff\xff")); } #[test] fn direct_i32_format_b_ok() { assert_eq!(from_bytes::(b"\xb0\x03\xfe\xff\xff").unwrap(), -65537); } #[test] fn direct_i32_format_b_ok_2() { assert_eq!( from_bytes::(b"\xb0\x04\xfe\xff\xff\xff").unwrap(), -16777217 ); } #[test] fn direct_i64_format_b() { assert_eq!(from_bytes::(b"\xb0\x01\xff").unwrap(), -1); assert_eq!(from_bytes::(b"\xb0\x03\xff\xff\xff").unwrap(), -1); assert_eq!( from_bytes::(b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1 ); assert_eq!(from_bytes::(b"\xb0\x01\xfe").unwrap(), -2); assert_eq!(from_bytes::(b"\xb0\x03\xff\xfe\xff").unwrap(), -257); assert_eq!(from_bytes::(b"\xb0\x03\xfe\xff\xff").unwrap(), -65537); assert_eq!( from_bytes::(b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217 ); assert_eq!( from_bytes::(b"\xb0\x0a\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937 ); expect_number_out_of_range(from_bytes::( b"\xb0\x0a\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff", )); expect_number_out_of_range(from_bytes::( b"\xb0\x09\xff\x0e\xff\xff\xff\xff\xff\xff\xff", )); expect_number_out_of_range(from_bytes::( b"\xb0\x09\x80\x0e\xff\xff\xff\xff\xff\xff\xff", )); expect_number_out_of_range(from_bytes::( b"\xb0\x0a\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff", )); assert_eq!( from_bytes::(b"\xb0\x08\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937 ); assert_eq!( from_bytes::(b"\xb0\x08\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039 ); assert_eq!( from_bytes::(b"\xb0\x08\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808 ); assert_eq!(from_bytes::(b"\xb0\x08\0\0\0\0\0\0\0\0").unwrap(), 0); assert_eq!(from_bytes::(b"\xB0\x00").unwrap(), 0); assert_eq!( from_bytes::(b"\xb0\x08\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807 ); } #[test] fn direct_u64_format_b() { expect_number_out_of_range(from_bytes::(b"\xb0\x01\xff")); assert_eq!(from_bytes::(b"\xb0\x02\0\xff").unwrap(), 255); expect_number_out_of_range(from_bytes::(b"\xb0\x03\xff\xff\xff")); assert_eq!(from_bytes::(b"\xb0\x04\0\xff\xff\xff").unwrap(), 0xffffff); expect_number_out_of_range(from_bytes::( b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", )); assert_eq!(from_bytes::(b"\xb0\x01\x02").unwrap(), 2); assert_eq!(from_bytes::(b"\xb0\x03\x00\x01\x00").unwrap(), 256); assert_eq!(from_bytes::(b"\xb0\x03\x01\x00\x00").unwrap(), 65536); assert_eq!( from_bytes::(b"\xb0\x0a\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216 ); assert_eq!( from_bytes::(b"\xb0\x0a\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936 ); assert_eq!( from_bytes::(b"\xb0\x0a\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000 ); assert_eq!( from_bytes::(b"\xb0\x0a\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000 ); expect_number_out_of_range(from_bytes::( b"\xb0\x0a\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00", )); assert_eq!( from_bytes::(b"\xb0\x09\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000 ); expect_number_out_of_range(from_bytes::( b"\xb0\x09\x7f\xf2\x00\x00\x00\x00\x00\x00\x00", )); expect_number_out_of_range(from_bytes::( b"\xb0\x0a\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00", )); assert_eq!( from_bytes::(b"\xb0\x08\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936 ); assert_eq!( from_bytes::(b"\xb0\x08\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039 ); expect_number_out_of_range(from_bytes::(b"\xb0\x08\x80\0\0\0\0\0\0\0")); assert_eq!( from_bytes::(b"\xb0\x09\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808 ); assert_eq!(from_bytes::(b"\xb0\x08\0\0\0\0\0\0\0\0").unwrap(), 0); assert_eq!(from_bytes::(b"\xB0\x00").unwrap(), 0); assert_eq!( from_bytes::(b"\xb0\x08\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807 ); } } #[cfg(test)] mod formatting_tests { use super::dom::Dom; use super::value::ArcValue; use super::value::IOValue; use super::value::Value; #[test] fn format_debug_and_parse() { let v = "[1, {z: 2, a: #!\"One\"}, 3]" .parse::>>() .unwrap(); assert_eq!(format!("{:?}", &v), "[1, {a: #!\"One\", z: 2}, 3]"); } #[test] fn format_pretty_debug_and_parse() { let v = "[1, {z: 2, a: #!\"One\"}, 3]" .parse::>>() .unwrap(); assert_eq!( format!("{:#?}", &v), concat!( "[\n", " 1,\n", " {\n", " a: #!\"One\",\n", " z: 2\n", " },\n", " 3\n", "]" ) ); } #[test] fn iovalue_parse() { let v = "[1 @{a:b c:d} @\"foo\" #![2 3] 4]" .parse::() .unwrap(); assert_eq!( format!("{:#?}", &v), concat!( "[\n", " 1,\n", " @{\n", " a: b,\n", " c: d\n", " } @\"foo\" #![\n", " 2,\n", " 3\n", " ],\n", " 4\n", "]" ) ); } } #[cfg(test)] mod serde_tests { use crate::de::from_bytes as deserialize_from_bytes; use crate::symbol::Symbol; use crate::value::de::from_value as deserialize_from_value; use crate::value::packed::PackedWriter; use crate::value::to_value; use crate::value::{IOValue, Map, Set, Value}; #[test] fn simple_to_value() { use serde::Serialize; #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] struct Colour { red: u8, green: u8, blue: u8, } #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)] struct SimpleValue<'a>( String, #[serde(with = "crate::symbol")] String, Symbol, #[serde(with = "crate::symbol")] String, Symbol, &'a str, #[serde(with = "serde_bytes")] &'a [u8], #[serde(with = "serde_bytes")] Vec, Vec, #[serde(with = "crate::set")] Set, i16, IOValue, Map, f32, f64, ); let mut str_set = Set::new(); str_set.insert("one".to_owned()); str_set.insert("two".to_owned()); str_set.insert("three".to_owned()); let mut colours = Map::new(); colours.insert( "red".to_owned(), Colour { red: 255, green: 0, blue: 0, }, ); colours.insert( "green".to_owned(), Colour { red: 0, green: 255, blue: 0, }, ); colours.insert( "blue".to_owned(), Colour { red: 0, green: 0, blue: 255, }, ); let v = SimpleValue( "hello".to_string(), "sym1".to_string(), Symbol("sym2".to_string()), "sym3".to_string(), Symbol("sym4".to_string()), "world", &b"slice"[..], b"vec".to_vec(), vec![false, true, false, true], str_set, 12345, Value::from("hi").wrap(), colours, 12.345f32, 12.3456789, ); println!("== v: {:#?}", v); let w: IOValue = to_value(&v); println!("== w: {:#?}", w); let x = deserialize_from_value(&w).unwrap(); println!("== x: {:#?}", &x); assert_eq!(v, x); let expected_bytes = vec![ 0xb4, // Struct 0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue 0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello" 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4 0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world" 0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice" 0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec" 0xb5, // Sequence 0x80, // false 0x81, // true 0x80, // false 0x81, // true 0x84, 0xb6, // Set 0xb1, 0x03, 0x6f, 0x6e, 0x65, 0xb1, 0x03, 0x74, 0x77, 0x6f, 0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65, 0x84, 0xb0, 0x02, 0x30, 0x39, // 12345 0xb1, 0x02, 0x68, 0x69, // "hi" 0xb7, // Dictionary 0xb1, 0x03, 0x72, 0x65, 0x64, // "red" 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xb0, 0x02, 0x00, 0xff, 0xb0, 0x00, 0xb0, 0x00, 0x84, 0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue" 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xb0, 0x00, 0xb0, 0x00, 0xb0, 0x02, 0x00, 0xff, 0x84, 0xb1, 0x05, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green" 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xb0, 0x00, 0xb0, 0x02, 0x00, 0xff, 0xb0, 0x00, 0x84, 0x84, 0x87, 0x08, 0x40, 0x28, 0xb0, 0xa3, 0xe0, 0x00, 0x00, 0x00, // 12.345f32 0x87, 0x08, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789 0x84, ]; let y = deserialize_from_bytes(&expected_bytes).unwrap(); println!("== y: {:#?}", &y); assert_eq!(v, y); let v_bytes_1 = PackedWriter::encode_iovalue(&w).unwrap(); println!("== w bytes = {:?}", v_bytes_1); assert_eq!(expected_bytes, v_bytes_1); let mut v_bytes_2 = Vec::new(); v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new( &mut v_bytes_2, ))) .unwrap(); println!("== v bytes = {:?}", v_bytes_2); assert_eq!(v_bytes_1, v_bytes_2); } }