preserves 5.0.0-rc.9

Implementation of the Preserves serialization format.
Documentation
pub mod de;
pub mod error;
pub mod ser;
pub mod set;
pub mod symbol;
pub mod value;

pub use de::from_bytes;
pub use de::from_text;
pub use de::from_read;
pub use error::Error;
pub use ser::to_writer;
pub use value::from_value;
pub use value::to_value;

#[cfg(test)]
mod decoder_tests {
    use crate::*;
    use crate::serde::de::from_bytes;
    use std::fmt::Debug;

    fn expect_number_out_of_range<T: Debug>(r: Result<T, crate::serde::Error>) {
        match r {
            Err(crate::serde::Error::Preserves(crate::Error::SyntaxError {
                detail: crate::SyntaxError::NumberOutOfRange(_), .. })) => (),
            _ => panic!("Expected NumberOutOfRange, but got {:?}", r),
        }
    }

    fn expect_expected<T: Debug>(k: ExpectedKind, r: Result<T, crate::serde::Error>) {
        match r {
            Err(crate::serde::Error::Preserves(crate::Error::SyntaxError {
                detail: crate::SyntaxError::Expected(k1), .. })) if k1 == k => (),
            _ => panic!("Expected Expected({:?}), but got {:?}", k, r)
        }
    }

    #[test] fn skip_annotations_noskip() {
        let v: IOValue = read_iovalue_packed(b"\x85\xb0\x01\x02\xb0\x01\x01", true).unwrap().into();
        assert_eq!(v.annotations().unwrap().len(), 1);
        assert_eq!(v.annotations().unwrap()[0], IOValue::new(2));
        assert_eq!(v, IOValue::new(1));
    }

    #[test] fn skip_annotations_skip() {
        let v: IOValue = read_iovalue_packed(b"\x85\xb0\x01\x02\xb0\x01\x01", false).unwrap().into();
        assert!(v.annotations().is_none());
        assert_eq!(v, IOValue::new(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 r = BytesBinarySource::new(&buf).into_packed();
        assert_eq!(r.source.index, 0);
        assert_eq!(r.next_iovalue(true).unwrap(), IOValue::record(IOValue::symbol("Ping"), vec![]).into());
        assert_eq!(r.source.index, 8);
        assert_eq!(r.next_iovalue(true).unwrap(), IOValue::record(IOValue::symbol("Pong"), vec![]).into());
        assert_eq!(r.source.index, 16);
        assert!(r.try_next_iovalue(true).unwrap().is_none());
    }

    #[test] fn direct_i8_format_a_positive()      { assert_eq!(from_bytes::<i8>(b"\xb0\x01\x01").unwrap(), 1) }
    #[test] fn direct_i8_format_a_zero()          { assert_eq!(from_bytes::<i8>(b"\xb0\x00").unwrap(), 0) }
    #[test] fn direct_i8_format_a_negative()      { assert_eq!(from_bytes::<i8>(b"\xb0\x01\xff").unwrap(), -1) }
    #[test] fn direct_i8_format_b()               { assert_eq!(from_bytes::<i8>(b"\xb0\x01\xfe").unwrap(), -2) }
    #[test] fn direct_i8_format_b_too_long()      { assert_eq!(from_bytes::<i8>(b"\xb0\x03\xff\xff\xfe").unwrap(), -2) }
    #[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(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::<u8>(b"\xb0\x01\x01").unwrap(), 1) }
    #[test] fn direct_u8_format_a_zero()          { assert_eq!(from_bytes::<u8>(b"\xb0\x00").unwrap(), 0) }
    #[test] fn direct_u8_format_b()               { assert_eq!(from_bytes::<u8>(b"\xb0\x011").unwrap(), 49) }
    #[test] fn direct_u8_format_b_too_long()      { assert_eq!(from_bytes::<u8>(b"\xb0\x04\0\0\01").unwrap(), 49) }
    #[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xb0\x0a\0\0\0\0\0\0\0\0\01").unwrap(), 49) }

    #[test] fn direct_i16_format_a()              { assert_eq!(from_bytes::<i16>(b"\xb0\x01\xfe").unwrap(), -2) }
    #[test] fn direct_i16_format_b()              { assert_eq!(from_bytes::<i16>(b"\xb0\x02\xfe\xff").unwrap(), -257) }

    #[test] fn direct_u8_wrong_format() {
        expect_expected::<u8>(ExpectedKind::SignedInteger, from_bytes(b"\xb1\x05bogus"))
    }

    #[test] fn direct_u8_format_b_too_large() {
        expect_number_out_of_range::<u8>(from_bytes(b"\xb0\x04\0\011"))
    }

    #[test] fn direct_i8_format_b_too_large() {
        expect_number_out_of_range::<i8>(from_bytes(b"\xb0\x02\xfe\xff"))
    }

    #[test] fn direct_i16_format_b_too_large() {
        expect_number_out_of_range::<i16>(from_bytes(b"\xb0\x03\xfe\xff\xff"));
    }

    #[test] fn direct_i32_format_b_ok() {
        assert_eq!(from_bytes::<i32>(b"\xb0\x03\xfe\xff\xff").unwrap(), -65537);
    }

    #[test] fn direct_i32_format_b_ok_2() {
        assert_eq!(from_bytes::<i32>(b"\xb0\x04\xfe\xff\xff\xff").unwrap(), -16777217);
    }

    #[test] fn direct_i64_format_b() {
        assert_eq!(from_bytes::<i64>(b"\xb0\x01\xff").unwrap(), -1);
        assert_eq!(from_bytes::<i64>(b"\xb0\x03\xff\xff\xff").unwrap(), -1);
        assert_eq!(from_bytes::<i64>(b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1);
        assert_eq!(from_bytes::<i64>(b"\xb0\x01\xfe").unwrap(), -2);
        assert_eq!(from_bytes::<i64>(b"\xb0\x03\xff\xfe\xff").unwrap(), -257);
        assert_eq!(from_bytes::<i64>(b"\xb0\x03\xfe\xff\xff").unwrap(), -65537);
        assert_eq!(from_bytes::<i64>(b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
        assert_eq!(from_bytes::<i64>(b"\xb0\x0a\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
        expect_number_out_of_range::<i64>(from_bytes(b"\xb0\x0a\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
        expect_number_out_of_range::<i64>(from_bytes(b"\xb0\x09\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
        expect_number_out_of_range::<i64>(from_bytes(b"\xb0\x09\x80\x0e\xff\xff\xff\xff\xff\xff\xff"));
        expect_number_out_of_range::<i64>(from_bytes(b"\xb0\x0a\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
        assert_eq!(from_bytes::<i64>(b"\xb0\x08\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
        assert_eq!(from_bytes::<i64>(b"\xb0\x08\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
        assert_eq!(from_bytes::<i64>(b"\xb0\x08\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
        assert_eq!(from_bytes::<i64>(b"\xb0\x08\0\0\0\0\0\0\0\0").unwrap(), 0);
        assert_eq!(from_bytes::<i64>(b"\xb0\x00").unwrap(), 0);
        assert_eq!(from_bytes::<i64>(b"\xb0\x08\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
    }

    #[test] fn direct_u64_format_b() {
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x01\xff"));
        assert_eq!(from_bytes::<u64>(b"\xb0\x02\0\xff").unwrap(), 255);
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x03\xff\xff\xff"));
        assert_eq!(from_bytes::<u64>(b"\xb0\x04\0\xff\xff\xff").unwrap(), 0xffffff);
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x0a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
        assert_eq!(from_bytes::<u64>(b"\xb0\x01\x02").unwrap(), 2);
        assert_eq!(from_bytes::<u64>(b"\xb0\x03\x00\x01\x00").unwrap(), 256);
        assert_eq!(from_bytes::<u64>(b"\xb0\x03\x01\x00\x00").unwrap(), 65536);
        assert_eq!(from_bytes::<u64>(b"\xb0\x0a\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
        assert_eq!(from_bytes::<u64>(b"\xb0\x0a\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
        assert_eq!(from_bytes::<u64>(b"\xb0\x0a\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
        assert_eq!(from_bytes::<u64>(b"\xb0\x0a\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x0a\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
        assert_eq!(from_bytes::<u64>(b"\xb0\x09\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x09\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x0a\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
        assert_eq!(from_bytes::<u64>(b"\xb0\x08\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
        assert_eq!(from_bytes::<u64>(b"\xb0\x08\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
        expect_number_out_of_range::<u64>(from_bytes(b"\xb0\x08\x80\0\0\0\0\0\0\0"));
        assert_eq!(from_bytes::<u64>(b"\xb0\x09\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
        assert_eq!(from_bytes::<u64>(b"\xb0\x08\0\0\0\0\0\0\0\0").unwrap(), 0);
        assert_eq!(from_bytes::<u64>(b"\xb0\x00").unwrap(), 0);
        assert_eq!(from_bytes::<u64>(b"\xb0\x08\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
    }
}

#[cfg(test)]
mod serde_tests {
    use crate::*;
    use super::de::from_bytes as deserialize_from_bytes;
    use super::value::de::from_value as deserialize_from_value;
    use super::value::to_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(String,
                           #[serde(with = "crate::serde::symbol")] String,
                           Symbol,
                           #[serde(with = "crate::serde::symbol")] String,
                           Symbol,
                           String,
                           #[serde(with = "serde_bytes")] Vec<u8>,
                           #[serde(with = "serde_bytes")] Vec<u8>,
                           Vec<bool>,
                           #[serde(with = "crate::serde::set")] Set<String>,
                           i16,
                           IOValue,
                           Map<String, Colour>,
                           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::new("sym2".to_string()),
                            "sym3".to_string(),
                            Symbol::new("sym4".to_string()),
                            "world".to_string(),
                            b"slice"[..].to_vec(),
                            b"vec".to_vec(),
                            vec![false, true, false, true],
                            str_set,
                            12345,
                            IOValue::new("hi"),
                            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::serde::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);
    }
}