diff --git a/implementations/rust/Cargo.toml b/implementations/rust/Cargo.toml index 648eae1..d011877 100644 --- a/implementations/rust/Cargo.toml +++ b/implementations/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "preserves" -version = "0.9.0" +version = "0.10.0" authors = ["Tony Garnock-Jones "] edition = "2018" description = "Implementation of the Preserves serialization format via serde." @@ -13,7 +13,6 @@ gitlab = { repository = "preserves/preserves" } [dependencies] num = "0.2" -num_enum = "0.4.1" serde = { version = "1.0", features = ["derive"] } serde_bytes = "0.11" lazy_static = "1.4.0" diff --git a/implementations/rust/benches/codec.rs b/implementations/rust/benches/codec.rs index 94a395d..ebe8979 100644 --- a/implementations/rust/benches/codec.rs +++ b/implementations/rust/benches/codec.rs @@ -38,7 +38,7 @@ pub fn bench_encoder(c: &mut Criterion) { let v = PackedReader::decode_read(&mut fh).demand_next(true).unwrap(); c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| { let mut bs = vec![]; - PackedWriter(&mut bs).write(&v).unwrap(); + PackedWriter::new(&mut bs).write(&v).unwrap(); bs })); } @@ -56,7 +56,7 @@ pub fn bench_ser(c: &mut Criterion) { let v: TestCases = de::from_read(&mut fh).unwrap(); c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| { let mut bs = vec![]; - ser::to_writer(&mut PackedWriter(&mut bs), &v).unwrap(); + ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap(); bs })); } @@ -74,7 +74,7 @@ pub fn bench_ser_encoder(c: &mut Criterion) { let v: TestCases = de::from_read(&mut fh).unwrap(); c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| { let mut bs = vec![]; - PackedWriter(&mut bs).write(&value::ser::to_value(&v)).unwrap(); + PackedWriter::new(&mut bs).write(&value::ser::to_value(&v)).unwrap(); bs })); } @@ -113,7 +113,7 @@ pub fn large_testdata_encoder(c: &mut Criterion) { } b.iter_with_large_drop(|| { let mut bs = vec![]; - let mut w = PackedWriter(&mut bs); + let mut w = PackedWriter::new(&mut bs); for v in &vs { w.write(&v).unwrap(); } diff --git a/implementations/rust/benches/testdata.bin.gz b/implementations/rust/benches/testdata.bin.gz index 4216b79..469262f 100644 Binary files a/implementations/rust/benches/testdata.bin.gz and b/implementations/rust/benches/testdata.bin.gz differ diff --git a/implementations/rust/src/de.rs b/implementations/rust/src/de.rs index 5968895..581e172 100644 --- a/implementations/rust/src/de.rs +++ b/implementations/rust/src/de.rs @@ -3,7 +3,7 @@ use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, Deseri use std::borrow::Cow; use std::marker::PhantomData; use super::value::PackedReader; -use super::value::reader::{Reader, IOBinarySource, BytesBinarySource, CompoundBody}; +use super::value::reader::{Reader, IOBinarySource, BytesBinarySource}; pub use super::error::Error; @@ -144,31 +144,31 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { - let (is_some, mut compound_body) = self.read.open_option()?; + let is_some = self.read.open_option()?; let result = if is_some { - compound_body.ensure_more_expected(self.read)?; + self.read.ensure_more_expected()?; visitor.visit_some(&mut *self)? } else { visitor.visit_none::()? }; - compound_body.ensure_complete(self.read)?; + self.read.ensure_complete()?; Ok(result) } fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de> { - let mut compound_body = self.read.open_simple_record("tuple", Some(0))?; + self.read.open_simple_record("tuple", Some(0))?; let result = visitor.visit_unit::()?; - compound_body.ensure_complete(self.read)?; + self.read.ensure_complete()?; Ok(result) } fn deserialize_unit_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de> { - let mut compound_body = self.read.open_simple_record(name, Some(0))?; + self.read.open_simple_record(name, Some(0))?; let result = visitor.visit_unit::()?; - compound_body.ensure_complete(self.read)?; + self.read.ensure_complete()?; Ok(result) } @@ -180,10 +180,10 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser { Some(v) => visitor.visit_u64(v), None => { - let mut compound_body = self.read.open_simple_record(name, Some(1))?; - compound_body.ensure_more_expected(self.read)?; + self.read.open_simple_record(name, Some(1))?; + self.read.ensure_more_expected()?; let result = visitor.visit_newtype_struct(&mut *self)?; - compound_body.ensure_complete(self.read)?; + self.read.ensure_complete()?; Ok(result) } } @@ -192,14 +192,14 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de> { // Hack around serde's model: Deserialize *sets* as sequences, // too, and reconstruct them as Rust Sets on the visitor side. - let compound_body = self.read.open_sequence_or_set()?; - visitor.visit_seq(Seq::new(self, compound_body)) + self.read.open_sequence_or_set()?; + visitor.visit_seq(Seq::new(self)) } fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de> { - let compound_body = self.read.open_simple_record("tuple", Some(len))?; - let mut seq = Seq::new(self, compound_body); + self.read.open_simple_record("tuple", Some(len))?; + let mut seq = Seq::new(self); let result = visitor.visit_seq(&mut seq)?; seq.skip_remainder()?; Ok(result) @@ -208,18 +208,17 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser fn deserialize_tuple_struct(self, name: &'static str, len: usize, visitor: V) -> Result where V: Visitor<'de> { - let compound_body = self.read.open_simple_record(name, Some(len))?; - let mut seq = Seq::new(self, compound_body); + self.read.open_simple_record(name, Some(len))?; + let mut seq = Seq::new(self); let result = visitor.visit_seq(&mut seq)?; seq.skip_remainder()?; Ok(result) } fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de> { - let compound_body = self.read.open_dictionary()?; - let mut seq = Seq::new(self, compound_body); + self.read.open_dictionary()?; + let mut seq = Seq::new(self); let result = visitor.visit_map(&mut seq)?; - seq.skip_remainder()?; Ok(result) } @@ -229,8 +228,8 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser visitor: V) -> Result where V: Visitor<'de> { - let compound_body = self.read.open_simple_record(name, Some(fields.len()))?; - let mut seq = Seq::new(self, compound_body); + self.read.open_simple_record(name, Some(fields.len()))?; + let mut seq = Seq::new(self); let result = visitor.visit_seq(&mut seq)?; seq.skip_remainder()?; Ok(result) @@ -261,24 +260,23 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser pub struct Seq<'de, 'r, 'a, R: Reader<'de>> { de: &'a mut Deserializer<'de, 'r, R>, - compound_body: CompoundBody, } impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> { - fn new(de: &'a mut Deserializer<'de, 'r, R>, compound_body: CompoundBody) -> Self { - Seq { de, compound_body } + fn new(de: &'a mut Deserializer<'de, 'r, R>) -> Self { + Seq { de } } fn skip_remainder(&mut self) -> Result<()> { - self.compound_body.skip_remainder(self.de.read) + self.de.read.skip_remainder() } fn next_item(&mut self, seed: T) -> Result> where T: DeserializeSeed<'de> { - match self.compound_body.more_expected(self.de.read)? { - false => Ok(None), - true => Ok(Some(seed.deserialize(&mut *self.de)?)), + match self.de.read.close_compound()? { + true => Ok(None), + false => Ok(Some(seed.deserialize(&mut *self.de)?)), } } } @@ -319,10 +317,9 @@ impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de, fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> { - let mut compound_body = self.read.open_record(None)?; - compound_body.ensure_more_expected(self.read)?; + self.read.open_record(None)?; let variant = seed.deserialize(&mut *self)?; - Ok((variant, Seq::new(self, compound_body))) + Ok((variant, Seq::new(self))) } } diff --git a/implementations/rust/src/lib.rs b/implementations/rust/src/lib.rs index 5ea8084..bba7940 100644 --- a/implementations/rust/src/lib.rs +++ b/implementations/rust/src/lib.rs @@ -24,7 +24,6 @@ mod dom { impl Domain for Dom { fn as_preserves(&self) -> Result { Ok(match self { - // TODO: How to nicely expose streaming values? Dom::One => Value::ByteString(vec![255, 255, 255, 255]).wrap(), Dom::Two => Value::symbol(&format!("Dom::{:?}", self)).wrap(), }) @@ -37,7 +36,7 @@ mod dom { Value::from(2).wrap()]) .wrap(); assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(), - [147, 49, 100, 255, 255, 255, 255, 50]); + [0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]); } #[test] fn test_two() { @@ -46,7 +45,7 @@ mod dom { Value::from(2).wrap()]) .wrap(); assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(), - [147, 49, 120, 68, 111, 109, 58, 58, 84, 119, 111, 50]); + [0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]); } } @@ -245,12 +244,12 @@ mod decoder_tests { 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), + Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e), } } #[test] fn skip_annotations_noskip() { - let mut buf = &b"\x0521"[..]; + let mut buf = &b"\x85\x92\x91"[..]; let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); let v = d.demand_next().unwrap(); assert_eq!(v.annotations().slice().len(), 1); @@ -259,7 +258,7 @@ mod decoder_tests { } #[test] fn skip_annotations_skip() { - let mut buf = &b"\x0521"[..]; + let mut buf = &b"\x85\x92\x91"[..]; let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); d.set_read_annotations(false); let v = d.demand_next().unwrap(); @@ -268,117 +267,103 @@ mod decoder_tests { } #[test] fn multiple_values_buf_advanced() { - let mut buf = &b"\x81tPing\x81tPong"[..]; - assert_eq!(buf.len(), 12); + let mut buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..]; + assert_eq!(buf.len(), 16); let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); assert_eq!(d.reader.source.index, 0); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping")); - assert_eq!(d.reader.source.index, 6); + assert_eq!(d.reader.source.index, 8); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong")); - assert_eq!(d.reader.source.index, 12); + 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"1").unwrap(), 1) } - #[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::(b"0").unwrap(), 0) } - #[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::(b"?").unwrap(), -1) } - #[test] fn direct_i8_format_b() { assert_eq!(from_bytes::(b"A\xfe").unwrap(), -2) } - #[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::(b"C\xff\xff\xfe").unwrap(), -2) } - #[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) } - #[test] fn direct_i8_format_c() { assert_eq!(from_bytes::(b"$a\xfe\x04").unwrap(), -2) } - #[test] fn direct_i8_format_c_too_long() { assert_eq!(from_bytes::(b"$a\xffa\xfe\x04").unwrap(), -2) } - #[test] fn direct_i8_format_c_much_too_long() { assert_eq!(from_bytes::(b"$a\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xfe\x04").unwrap(), -2) } + #[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::(b"\x91").unwrap(), 1) } + #[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::(b"\x90").unwrap(), 0) } + #[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::(b"\x9f").unwrap(), -1) } + #[test] fn direct_i8_format_b() { assert_eq!(from_bytes::(b"\xa0\xfe").unwrap(), -2) } + #[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::(b"\xa2\xff\xff\xfe").unwrap(), -2) } + #[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) } - #[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::(b"1").unwrap(), 1) } - #[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::(b"0").unwrap(), 0) } - #[test] fn direct_u8_format_b() { assert_eq!(from_bytes::(b"A1").unwrap(), 49) } - #[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::(b"D\0\0\01").unwrap(), 49) } - #[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::(b"J\0\0\0\0\0\0\0\0\01").unwrap(), 49) } - #[test] fn direct_u8_format_c() { assert_eq!(from_bytes::(b"$a1\x04").unwrap(), 49) } - #[test] fn direct_u8_format_c_too_long() { assert_eq!(from_bytes::(b"$a\0a1\x04").unwrap(), 49) } - #[test] fn direct_u8_format_c_much_too_long() { assert_eq!(from_bytes::(b"$a\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a1\x04").unwrap(), 49) } + #[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::(b"\x91").unwrap(), 1) } + #[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::(b"\x90").unwrap(), 0) } + #[test] fn direct_u8_format_b() { assert_eq!(from_bytes::(b"\xa01").unwrap(), 49) } + #[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::(b"\xa3\0\0\01").unwrap(), 49) } + #[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::(b"\xa9\0\0\0\0\0\0\0\0\01").unwrap(), 49) } - #[test] fn direct_i16_format_a() { assert_eq!(from_bytes::(b">").unwrap(), -2) } - #[test] fn direct_i16_format_b() { assert_eq!(from_bytes::(b"B\xfe\xff").unwrap(), -257) } + #[test] fn direct_i16_format_a() { assert_eq!(from_bytes::(b"\x9e").unwrap(), -2) } + #[test] fn direct_i16_format_b() { assert_eq!(from_bytes::(b"\xa1\xfe\xff").unwrap(), -257) } #[test] fn direct_u8_wrong_format() { - expect_expected(ExpectedKind::SignedInteger, from_bytes::(b"Ubogus")) + 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"D\0\011")) - } - - #[test] fn direct_u8_format_c_too_large() { - expect_number_out_of_range(from_bytes::(b"$a1a1\x04")) + expect_number_out_of_range(from_bytes::(b"\xa3\0\011")) } #[test] fn direct_i8_format_b_too_large() { - expect_number_out_of_range(from_bytes::(b"B\xfe\xff")) - } - - #[test] fn direct_i8_format_c_too_large() { - expect_number_out_of_range(from_bytes::(b"$a\xfea\xff\x04")) + expect_number_out_of_range(from_bytes::(b"\xa1\xfe\xff")) } #[test] fn direct_i16_format_b_too_large() { - expect_number_out_of_range(from_bytes::(b"C\xfe\xff\xff")); + expect_number_out_of_range(from_bytes::(b"\xa2\xfe\xff\xff")); } #[test] fn direct_i32_format_b_ok() { - assert_eq!(from_bytes::(b"C\xfe\xff\xff").unwrap(), -65537); + assert_eq!(from_bytes::(b"\xa2\xfe\xff\xff").unwrap(), -65537); } #[test] fn direct_i32_format_b_ok_2() { - assert_eq!(from_bytes::(b"D\xfe\xff\xff\xff").unwrap(), -16777217); + assert_eq!(from_bytes::(b"\xa3\xfe\xff\xff\xff").unwrap(), -16777217); } #[test] fn direct_i64_format_b() { - assert_eq!(from_bytes::(b"A\xff").unwrap(), -1); - assert_eq!(from_bytes::(b"C\xff\xff\xff").unwrap(), -1); - assert_eq!(from_bytes::(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1); - assert_eq!(from_bytes::(b"A\xfe").unwrap(), -2); - assert_eq!(from_bytes::(b"C\xff\xfe\xff").unwrap(), -257); - assert_eq!(from_bytes::(b"C\xfe\xff\xff").unwrap(), -65537); - assert_eq!(from_bytes::(b"J\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217); - assert_eq!(from_bytes::(b"J\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); - expect_number_out_of_range(from_bytes::(b"J\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); - expect_number_out_of_range(from_bytes::(b"I\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); - expect_number_out_of_range(from_bytes::(b"I\x80\x0e\xff\xff\xff\xff\xff\xff\xff")); - expect_number_out_of_range(from_bytes::(b"J\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff")); - assert_eq!(from_bytes::(b"H\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); - assert_eq!(from_bytes::(b"H\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); - assert_eq!(from_bytes::(b"H\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808); - assert_eq!(from_bytes::(b"H\0\0\0\0\0\0\0\0").unwrap(), 0); - assert_eq!(from_bytes::(b"@").unwrap(), 0); - assert_eq!(from_bytes::(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); + assert_eq!(from_bytes::(b"\xa0\xff").unwrap(), -1); + assert_eq!(from_bytes::(b"\xa2\xff\xff\xff").unwrap(), -1); + assert_eq!(from_bytes::(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1); + assert_eq!(from_bytes::(b"\xa0\xfe").unwrap(), -2); + assert_eq!(from_bytes::(b"\xa2\xff\xfe\xff").unwrap(), -257); + assert_eq!(from_bytes::(b"\xa2\xfe\xff\xff").unwrap(), -65537); + assert_eq!(from_bytes::(b"\xa9\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217); + assert_eq!(from_bytes::(b"\xa9\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); + expect_number_out_of_range(from_bytes::(b"\xa9\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); + expect_number_out_of_range(from_bytes::(b"\xa8\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); + expect_number_out_of_range(from_bytes::(b"\xa8\x80\x0e\xff\xff\xff\xff\xff\xff\xff")); + expect_number_out_of_range(from_bytes::(b"\xa9\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff")); + assert_eq!(from_bytes::(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); + assert_eq!(from_bytes::(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); + assert_eq!(from_bytes::(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808); + assert_eq!(from_bytes::(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0); + assert_eq!(from_bytes::(b"\x90").unwrap(), 0); + assert_eq!(from_bytes::(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); } #[test] fn direct_u64_format_b() { - expect_number_out_of_range(from_bytes::(b"A\xff")); - assert_eq!(from_bytes::(b"B\0\xff").unwrap(), 255); - expect_number_out_of_range(from_bytes::(b"C\xff\xff\xff")); - assert_eq!(from_bytes::(b"D\0\xff\xff\xff").unwrap(), 0xffffff); - expect_number_out_of_range(from_bytes::(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")); - assert_eq!(from_bytes::(b"A\x02").unwrap(), 2); - assert_eq!(from_bytes::(b"C\x00\x01\x00").unwrap(), 256); - assert_eq!(from_bytes::(b"C\x01\x00\x00").unwrap(), 65536); - assert_eq!(from_bytes::(b"J\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216); - assert_eq!(from_bytes::(b"J\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); - assert_eq!(from_bytes::(b"J\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); - assert_eq!(from_bytes::(b"J\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000); - expect_number_out_of_range(from_bytes::(b"J\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00")); - assert_eq!(from_bytes::(b"I\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); - expect_number_out_of_range(from_bytes::(b"I\x7f\xf2\x00\x00\x00\x00\x00\x00\x00")); - expect_number_out_of_range(from_bytes::(b"J\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00")); - assert_eq!(from_bytes::(b"H\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); - assert_eq!(from_bytes::(b"H\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); - expect_number_out_of_range(from_bytes::(b"H\x80\0\0\0\0\0\0\0")); - assert_eq!(from_bytes::(b"I\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808); - assert_eq!(from_bytes::(b"H\0\0\0\0\0\0\0\0").unwrap(), 0); - assert_eq!(from_bytes::(b"@").unwrap(), 0); - assert_eq!(from_bytes::(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); + expect_number_out_of_range(from_bytes::(b"\xa0\xff")); + assert_eq!(from_bytes::(b"\xa1\0\xff").unwrap(), 255); + expect_number_out_of_range(from_bytes::(b"\xa2\xff\xff\xff")); + assert_eq!(from_bytes::(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff); + expect_number_out_of_range(from_bytes::(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")); + assert_eq!(from_bytes::(b"\xa0\x02").unwrap(), 2); + assert_eq!(from_bytes::(b"\xa2\x00\x01\x00").unwrap(), 256); + assert_eq!(from_bytes::(b"\xa2\x01\x00\x00").unwrap(), 65536); + assert_eq!(from_bytes::(b"\xa9\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216); + assert_eq!(from_bytes::(b"\xa9\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); + assert_eq!(from_bytes::(b"\xa9\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); + assert_eq!(from_bytes::(b"\xa9\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000); + expect_number_out_of_range(from_bytes::(b"\xa9\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00")); + assert_eq!(from_bytes::(b"\xa8\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); + expect_number_out_of_range(from_bytes::(b"\xa8\x7f\xf2\x00\x00\x00\x00\x00\x00\x00")); + expect_number_out_of_range(from_bytes::(b"\xa9\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00")); + assert_eq!(from_bytes::(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); + assert_eq!(from_bytes::(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); + expect_number_out_of_range(from_bytes::(b"\xa7\x80\0\0\0\0\0\0\0")); + assert_eq!(from_bytes::(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808); + assert_eq!(from_bytes::(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0); + assert_eq!(from_bytes::(b"\x90").unwrap(), 0); + assert_eq!(from_bytes::(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); } } @@ -442,50 +427,54 @@ mod serde_tests { assert_eq!(v, x); let expected_bytes = vec![ - 0x8f, 0x10, // Struct, 15 members + 1 label - 0x7b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue - 0x55, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello" - 0x74, 0x73, 0x79, 0x6d, 0x31, // sym1 - 0x74, 0x73, 0x79, 0x6d, 0x32, // sym2 - 0x74, 0x73, 0x79, 0x6d, 0x33, // sym3 - 0x74, 0x73, 0x79, 0x6d, 0x34, // sym4 - 0x55, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world" - 0x65, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice" - 0x63, 0x76, 0x65, 0x63, // #"vec" - 0x94, // Sequence, 4 items - 0x0, // false - 0x1, // true - 0x0, // false - 0x1, // true - 0xa3, // Set, 3 items - 0x53, 0x6f, 0x6e, 0x65, - 0x55, 0x74, 0x68, 0x72, 0x65, 0x65, - 0x53, 0x74, 0x77, 0x6f, - 0x42, 0x30, 0x39, // 12345 - 0x52, 0x68, 0x69, // "hi" - 0xb6, // Dictionary, 6 items = 3 key/value pairs - 0x54, 0x62, 0x6c, 0x75, 0x65, // "blue" - 0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x30, 0x42, 0x00, 0xff, - 0x55, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green" - 0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x42, 0x00, 0xff, 0x30, - 0x53, 0x72, 0x65, 0x64, // "red" - 0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x42, 0x00, 0xff, 0x30, 0x30, + 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, + 0xa1, 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, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84, + 0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue" + 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0x90, 0xa1, 0x00, 0xff, 0x84, + 0xb1, 0x05, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green" + 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0xa1, 0x00, 0xff, 0x90, 0x84, + 0x84, - 0x2, 0x41, 0x45, 0x85, 0x1f, // 12.345, - 0x3, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789 + 0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345, + 0x83, 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(&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(&mut v_bytes_2))).unwrap(); + 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); - - let y = deserialize_from_bytes(&v_bytes_1).unwrap(); - println!("== y: {:#?}", &y); - assert_eq!(v, y); } } diff --git a/implementations/rust/src/ser.rs b/implementations/rust/src/ser.rs index 2c20ee9..696d310 100644 --- a/implementations/rust/src/ser.rs +++ b/implementations/rust/src/ser.rs @@ -1,43 +1,42 @@ use serde::Serialize; -use super::value::writer::Writer; +use super::value::writer::{Writer, CompoundWriter}; pub use super::error::Error; type Result = std::result::Result; #[derive(Debug)] -pub struct Serializer<'a, W: Writer> { - pub write: &'a mut W, +pub struct Serializer<'w, W: Writer> { + pub write: &'w mut W, } -impl<'a, W: Writer> Serializer<'a, W> { - pub fn new(write: &'a mut W) -> Self { +impl<'w, W: Writer> Serializer<'w, W> { + pub fn new(write: &'w mut W) -> Self { Serializer { write } } } #[derive(Debug)] -pub struct SerializeCompound<'a, 'b, W: Writer> { - ser: &'a mut Serializer<'b, W>, - c: W::Compound, +pub struct SerializeCompound<'a, 'w, W: Writer> { + ser: &'a mut Serializer<'w, W>, + c: W::SeqWriter, } #[derive(Debug)] -pub struct SerializeDictionary<'a, 'b, W: Writer> { - ser: &'a mut Serializer<'b, W>, - d: W::Dictionary, - key_p: Option, +pub struct SerializeDictionary<'a, 'w, W: Writer> { + ser: &'a mut Serializer<'w, W>, + d: W::SetWriter, } -impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> { + type Ok = (); type Error = Error; - type SerializeSeq = SerializeCompound<'a, 'b, W>; - type SerializeTuple = SerializeCompound<'a, 'b, W>; - type SerializeTupleStruct = SerializeCompound<'a, 'b, W>; - type SerializeTupleVariant = SerializeCompound<'a, 'b, W>; - type SerializeMap = SerializeDictionary<'a, 'b, W>; - type SerializeStruct = SerializeCompound<'a, 'b, W>; - type SerializeStructVariant = SerializeCompound<'a, 'b, W>; + type SerializeSeq = SerializeCompound<'a, 'w, W>; + type SerializeTuple = SerializeCompound<'a, 'w, W>; + type SerializeTupleStruct = SerializeCompound<'a, 'w, W>; + type SerializeTupleVariant = SerializeCompound<'a, 'w, W>; + type SerializeMap = SerializeDictionary<'a, 'w, W>; + type SerializeStruct = SerializeCompound<'a, 'w, W>; + type SerializeStructVariant = SerializeCompound<'a, 'w, W>; fn serialize_bool(self, v: bool) -> Result { Ok(self.write.write_bool(v)?) @@ -84,12 +83,14 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { } fn serialize_char(self, v: char) -> Result { - let mut c = self.write.start_record(1)?; - let p = self.write.write_symbol("UnicodeScalar")?; - self.write.extend_compound(&mut c, p)?; - let p = self.write.write_u32(v as u32)?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(1))?; + c.extend()?; + c.write_symbol("UnicodeScalar")?; + c.delimit()?; + c.extend()?; + c.write_u32(v as u32)?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_str(self, v: &str) -> Result { @@ -101,33 +102,38 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { } fn serialize_none(self) -> Result { - let mut c = self.write.start_record(0)?; - let p = self.write.write_symbol("None")?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(0))?; + c.extend()?; + c.write_symbol("None")?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_some(self, v: &T) -> Result where T: Serialize { - let mut c = self.write.start_record(1)?; - let p = self.write.write_symbol("Some")?; - self.write.extend_compound(&mut c, p)?; - let p = v.serialize(&mut *self)?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(1))?; + c.extend()?; + c.write_symbol("Some")?; + c.delimit()?; + c.extend()?; + to_writer(&mut c, v)?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_unit(self) -> Result { - let mut c = self.write.start_record(0)?; - let p = self.write.write_symbol("tuple")?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(0))?; + c.extend()?; + c.write_symbol("tuple")?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_unit_struct(self, name: &'static str) -> Result { - let mut c = self.write.start_record(0)?; - let p = self.write.write_symbol(name)?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(0))?; + c.extend()?; + c.write_symbol(name)?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_unit_variant(self, @@ -136,27 +142,28 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { variant_name: &'static str) -> Result { - let mut c = self.write.start_record(0)?; - let p = self.write.write_symbol(variant_name)?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(0))?; + c.extend()?; + c.write_symbol(variant_name)?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result where T: Serialize { match super::value::magic::receive_output_value(name, value) { - Some(v) => { - Ok(self.write.write(&v)?) - } + Some(v) => Ok(self.write.write(&v)?), None => { // TODO: This is apparently discouraged, and we should apparently just serialize `value`? - let mut c = self.write.start_record(1)?; - let p = self.write.write_symbol(name)?; - self.write.extend_compound(&mut c, p)?; - let p = value.serialize(&mut *self)?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(1))?; + c.extend()?; + c.write_symbol(name)?; + c.delimit()?; + c.extend()?; + to_writer(&mut c, value)?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } } } @@ -168,38 +175,36 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { value: &T) -> Result where T: Serialize { - let mut c = self.write.start_record(1)?; - let p = self.write.write_symbol(variant_name)?; - self.write.extend_compound(&mut c, p)?; - let p = value.serialize(&mut *self)?; - self.write.extend_compound(&mut c, p)?; - Ok(self.write.end_compound(c)?) + let mut c = self.write.start_record(Some(1))?; + c.extend()?; + c.write_symbol(variant_name)?; + c.delimit()?; + c.extend()?; + to_writer(&mut c, value)?; + c.delimit()?; + Ok(self.write.end_seq(c)?) } fn serialize_seq(self, count: Option) -> Result { - let c = match count { - Some(n) => self.write.start_sequence(n)?, - None => match self.write.stream_sequence()? { - Some(c) => c, - None => return Err(Error::StreamingSerializationUnsupported), - } - }; + let c = self.write.start_sequence(count)?; Ok(SerializeCompound { ser: self, c }) } fn serialize_tuple(self, count: usize) -> Result { - let mut c = self.write.start_record(count)?; - let p = self.write.write_symbol("tuple")?; - self.write.extend_compound(&mut c, p)?; + let mut c = self.write.start_record(Some(count))?; + c.extend()?; + c.write_symbol("tuple")?; + c.delimit()?; Ok(SerializeCompound { ser: self, c }) } fn serialize_tuple_struct(self, name: &'static str, count: usize) -> Result { - let mut c = self.write.start_record(count)?; - let p = self.write.write_symbol(name)?; - self.write.extend_compound(&mut c, p)?; + let mut c = self.write.start_record(Some(count))?; + c.extend()?; + c.write_symbol(name)?; + c.delimit()?; Ok(SerializeCompound { ser: self, c }) } @@ -210,27 +215,23 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { count: usize) -> Result { - let mut c = self.write.start_record(count)?; - let p = self.write.write_symbol(variant_name)?; - self.write.extend_compound(&mut c, p)?; + let mut c = self.write.start_record(Some(count))?; + c.extend()?; + c.write_symbol(variant_name)?; + c.delimit()?; Ok(SerializeCompound { ser: self, c }) } fn serialize_map(self, count: Option) -> Result { - let d = match count { - Some(n) => self.write.start_dictionary(n)?, - None => match self.write.stream_dictionary()? { - Some(d) => d, - None => return Err(Error::StreamingSerializationUnsupported), - } - }; - Ok(SerializeDictionary { ser: self, d, key_p: None }) + let d = self.write.start_dictionary(count)?; + Ok(SerializeDictionary { ser: self, d }) } fn serialize_struct(self, name: &'static str, count: usize) -> Result { - let mut c = self.write.start_record(count)?; - let p = self.write.write_symbol(name)?; - self.write.extend_compound(&mut c, p)?; + let mut c = self.write.start_record(Some(count))?; + c.extend()?; + c.write_symbol(name)?; + c.delimit()?; Ok(SerializeCompound { ser: self, c }) } @@ -241,122 +242,130 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { count: usize) -> Result { - let mut c = self.write.start_record(count)?; - let p = self.write.write_symbol(variant_name)?; - self.write.extend_compound(&mut c, p)?; + let mut c = self.write.start_record(Some(count))?; + c.extend()?; + c.write_symbol(variant_name)?; + c.delimit()?; Ok(SerializeCompound { ser: self, c }) } } -impl<'a, 'b, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_key(&mut self, key: &T) -> Result<()> where T: Serialize { - let kp1 = key.serialize(&mut *self.ser)?; - self.key_p = Some(self.ser.write.extend_dictionary_key(&mut self.d, kp1)?); + self.d.extend()?; + to_writer(&mut self.d, key)?; Ok(()) } fn serialize_value(&mut self, value: &T) -> Result<()> where T: Serialize { - let vp1 = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_dictionary_value(&mut self.d, self.key_p.take().unwrap(), vp1)?) + to_writer(&mut self.d, value)?; + Ok(self.d.delimit()?) } fn end(self) -> Result { - Ok(self.ser.write.end_dictionary(self.d)?) + Ok(self.ser.write.end_set(self.d)?) } } -impl<'a, 'b, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> { + fn extend(&mut self, value: &T) -> Result<()> + where T: Serialize + { + self.c.extend()?; + to_writer(&mut self.c, value)?; + Ok(self.c.delimit()?) + } + + fn complete(self) -> Result<()> { + Ok(self.ser.write.end_seq(self.c)?) + } +} + +impl<'a, 'w, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_field(&mut self, _name: &'static str, value: &T) -> Result<()> where T: Serialize { - let p = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_compound(&mut self.c, p)?) + self.extend(value) } fn end(self) -> Result { - Ok(self.ser.write.end_compound(self.c)?) + self.complete() } } -impl<'a, 'b, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_field(&mut self, _name: &'static str, value: &T) -> Result<()> where T: Serialize { - let p = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_compound(&mut self.c, p)?) + self.extend(value) } fn end(self) -> Result { - Ok(self.ser.write.end_compound(self.c)?) + self.complete() } } -impl<'a, 'b, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<()> where T: Serialize { - let p = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_compound(&mut self.c, p)?) + self.extend(value) } fn end(self) -> Result { - Ok(self.ser.write.end_compound(self.c)?) + self.complete() } } -impl<'a, 'b, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<()> where T: Serialize { - let p = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_compound(&mut self.c, p)?) + self.extend(value) } fn end(self) -> Result { - Ok(self.ser.write.end_compound(self.c)?) + self.complete() } } -impl<'a, 'b, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<()> where T: Serialize { - let p = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_compound(&mut self.c, p)?) + self.extend(value) } fn end(self) -> Result { - Ok(self.ser.write.end_compound(self.c)?) + self.complete() } } -impl<'a, 'b, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'b, W> { - type Ok = W::Pointer; +impl<'a, 'w, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'w, W> { + type Ok = (); type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<()> where T: Serialize { - let p = value.serialize(&mut *self.ser)?; - Ok(self.ser.write.extend_compound(&mut self.c, p)?) + self.extend(value) } fn end(self) -> Result { - Ok(self.ser.write.end_compound(self.c)?) + self.complete() } } -pub fn to_writer(write: &mut W, value: &T) -> Result { - let mut ser: Serializer<'_, W> = Serializer::new(write); - value.serialize(&mut ser) +pub fn to_writer(write: &mut W, value: &T) -> Result<()> { + Ok(value.serialize(&mut Serializer::new(write))?) } diff --git a/implementations/rust/src/value/packed/constants.rs b/implementations/rust/src/value/packed/constants.rs index 6cca5f1..2b20132 100644 --- a/implementations/rust/src/value/packed/constants.rs +++ b/implementations/rust/src/value/packed/constants.rs @@ -1,68 +1,86 @@ use std::convert::{TryFrom, From}; -use num_enum::TryFromPrimitive; #[derive(Debug, PartialEq, Eq)] -pub enum Op { - Misc(u8), - Atom(AtomMinor), - Compound(CompoundMinor), - Reserved(u8), +pub enum Tag { + False, + True, + Float, + Double, + End, + Annotation, + SmallInteger(i8), + MediumInteger(u8), + SignedInteger, + String, + ByteString, + Symbol, + Record, + Sequence, + Set, + Dictionary, } #[derive(Debug, PartialEq, Eq)] -pub struct InvalidOp; +pub struct InvalidTag(u8); -impl From for std::io::Error { - fn from(_v: InvalidOp) -> Self { +impl From for std::io::Error { + fn from(v: InvalidTag) -> Self { std::io::Error::new(std::io::ErrorKind::InvalidData, - "Invalid Preserves lead byte major value") + format!("Invalid Preserves tag {}", v.0).to_string()) } } -impl From for crate::error::Error { - fn from(v: InvalidOp) -> Self { +impl From for crate::error::Error { + fn from(v: InvalidTag) -> Self { crate::error::Error::Io(v.into()) } } -impl TryFrom for Op { - type Error = InvalidOp; +impl TryFrom for Tag { + type Error = InvalidTag; fn try_from(v: u8) -> Result { - match v >> 2 { - 0 => Ok(Self::Misc(v & 3)), - 1 => Ok(Self::Atom(AtomMinor::try_from(v & 3).unwrap())), - 2 => Ok(Self::Compound(CompoundMinor::try_from(v & 3).unwrap())), - 3 => Ok(Self::Reserved(v & 3)), - _ => Err(InvalidOp), - } - } -} - -impl From for u8 { - fn from(v: Op) -> Self { match v { - Op::Misc(minor) => minor & 3, - Op::Atom(minor) => (1 << 2) | ((minor as u8) & 3), - Op::Compound(minor) => (2 << 2) | ((minor as u8) & 3), - Op::Reserved(minor) => (3 << 2) | (minor & 3), + 0x80 => Ok(Self::False), + 0x81 => Ok(Self::True), + 0x82 => Ok(Self::Float), + 0x83 => Ok(Self::Double), + 0x84 => Ok(Self::End), + 0x85 => Ok(Self::Annotation), + 0x90..=0x9c => Ok(Self::SmallInteger((v - 0x90) as i8)), + 0x9d..=0x9f => Ok(Self::SmallInteger((v - 0x90) as i8 - 16)), + 0xa0..=0xaf => Ok(Self::MediumInteger(v - 0xa0 + 1)), + 0xb0 => Ok(Self::SignedInteger), + 0xb1 => Ok(Self::String), + 0xb2 => Ok(Self::ByteString), + 0xb3 => Ok(Self::Symbol), + 0xb4 => Ok(Self::Record), + 0xb5 => Ok(Self::Sequence), + 0xb6 => Ok(Self::Set), + 0xb7 => Ok(Self::Dictionary), + _ => Err(InvalidTag(v)) } } } -#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)] -#[repr(u8)] -pub enum AtomMinor { - SignedInteger = 0, - String = 1, - ByteString = 2, - Symbol = 3, -} - -#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)] -#[repr(u8)] -pub enum CompoundMinor { - Record = 0, - Sequence = 1, - Set = 2, - Dictionary = 3, +impl From for u8 { + fn from(v: Tag) -> Self { + match v { + Tag::False => 0x80, + Tag::True => 0x81, + Tag::Float => 0x82, + Tag::Double => 0x83, + Tag::End => 0x84, + Tag::Annotation => 0x85, + Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 }, + Tag::MediumInteger(count) => count - 1 + 0xa0, + Tag::SignedInteger => 0xb0, + Tag::String => 0xb1, + Tag::ByteString => 0xb2, + Tag::Symbol => 0xb3, + Tag::Record => 0xb4, + Tag::Sequence => 0xb5, + Tag::Set => 0xb6, + Tag::Dictionary => 0xb7, + } + } } diff --git a/implementations/rust/src/value/packed/reader.rs b/implementations/rust/src/value/packed/reader.rs index 58cf828..a71d15b 100644 --- a/implementations/rust/src/value/packed/reader.rs +++ b/implementations/rust/src/value/packed/reader.rs @@ -7,12 +7,10 @@ use std::marker::PhantomData; use super::super::signed_integer::SignedInteger; use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations}; -use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor}; +use super::constants::Tag; use super::super::reader::{ BinarySource, BytesBinarySource, - CompoundBody, - CompoundLimit, ConfiguredReader, IOBinarySource, IOResult, @@ -87,16 +85,8 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> { } } - fn wirelength(&mut self, arg: u8) -> IOResult { - if arg < 15 { - Ok(usize::from(arg)) - } else { - self.varint() - } - } - fn peekend(&mut self) -> IOResult { - if self.peek()? == 4 { + if self.peek()? == Tag::End.into() { self.skip()?; Ok(true) } else { @@ -104,28 +94,10 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> { } } - fn gather_chunks(&mut self) -> IOResult> { - let mut bs = Vec::with_capacity(256); - while !self.peekend()? { - match decodeop(self.peek()?)? { - (Op::Atom(AtomMinor::ByteString), arg) => { - self.skip()?; - let count = self.wirelength(arg)?; - if count == 0 { - return Err(io_syntax_error("Empty binary chunks are forbidden")); - } - bs.extend_from_slice(&self.readbytes(count)?) - }, - _ => return Err(io_syntax_error("Unexpected non-format-B-ByteString chunk")) - } - } - Ok(bs) - } - - fn peek_next_nonannotation_op(&mut self) -> ReaderResult<(Op, u8)> { + fn peek_next_nonannotation_tag(&mut self) -> ReaderResult { loop { - match decodeop(self.peek()?)? { - (Op::Misc(0), 5) => { + match Tag::try_from(self.peek()?)? { + Tag::Annotation => { self.skip()?; self.skip_value()?; }, @@ -134,44 +106,29 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> { } } - fn next_atomic(&mut self, minor: AtomMinor, k: ExpectedKind) -> ReaderResult> { - match self.peek_next_nonannotation_op()? { - (Op::Atom(actual_minor), arg) if actual_minor == minor => { - self.skip()?; - let count = self.wirelength(arg)?; - Ok(self.readbytes(count)?) - } - (Op::Misc(2), arg) => match Op::try_from(arg)? { - Op::Atom(actual_minor) if actual_minor == minor => { - self.skip()?; - Ok(Cow::Owned(self.gather_chunks()?)) - } - _ => Err(self.expected(k)), - }, - _ => Err(self.expected(k)), + fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult> { + let actual_tag = self.peek_next_nonannotation_tag()?; + if actual_tag == expected_tag { + self.skip()?; + let count = self.varint()?; + Ok(self.readbytes(count)?) + } else { + Err(self.expected(k)) } } - fn next_compound(&mut self, minor: CompoundMinor, k: ExpectedKind) -> - ReaderResult> + fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()> { - match self.peek_next_nonannotation_op()? { - (Op::Compound(actual_minor), arg) if actual_minor == minor => { - self.skip()?; - Ok(CompoundBody::counted(minor, self.wirelength(arg)?)) - } - (Op::Misc(2), arg) => match Op::try_from(arg)? { - Op::Compound(actual_minor) if actual_minor == minor => { - self.skip()?; - Ok(CompoundBody::streaming(minor)) - } - _ => Err(self.expected(k)), - }, - _ => Err(self.expected(k)), + let actual_tag = self.peek_next_nonannotation_tag()?; + if actual_tag == expected_tag { + self.skip()?; + Ok(()) + } else { + Err(self.expected(k)) } } - fn read_number_format_b(&mut self, count: usize) -> IOResult { + fn read_signed_integer(&mut self, count: usize) -> IOResult { if count == 0 { return Ok(SignedInteger::from(0 as i128)); } @@ -211,28 +168,30 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> { where F: FnOnce(u128) -> Option { - match self.peek_next_nonannotation_op()? { - (Op::Misc(3), arg) => { + let tag = self.peek_next_nonannotation_tag()?; + match tag { + Tag::SmallInteger(v) => { self.skip()?; - if arg > 12 { - Err(out_of_range((arg as i8) - 16)) + if v < 0 { + Err(out_of_range(v)) } else { - f(arg as u128).ok_or_else(|| out_of_range(arg)) + f(v as u128).ok_or_else(|| out_of_range(v)) } } - (Op::Atom(AtomMinor::SignedInteger), arg) => { + Tag::MediumInteger(count) => { self.skip()?; - let count = self.wirelength(arg)?; - let n = &self.read_number_format_b(count)?; + let n = &self.read_signed_integer(count.into())?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } - _ => { - let n_value = self.demand_next(false)?; - let n = n_value.value().to_signedinteger()?; + Tag::SignedInteger => { + self.skip()?; + let count = self.varint()?; + let n = &self.read_signed_integer(count)?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } + _ => Err(self.expected(ExpectedKind::SignedInteger)) } } @@ -240,166 +199,169 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> { where F: FnOnce(i128) -> Option { - match self.peek_next_nonannotation_op()? { - (Op::Misc(3), arg) => { + let tag = self.peek_next_nonannotation_tag()?; + match tag { + Tag::SmallInteger(v) => { self.skip()?; - let n = arg as i128; - let n = if n > 12 { n - 16 } else { n }; - f(n).ok_or_else(|| out_of_range(n)) + f(v.into()).ok_or_else(|| out_of_range(v)) } - (Op::Atom(AtomMinor::SignedInteger), arg) => { + Tag::MediumInteger(count) => { self.skip()?; - let count = self.wirelength(arg)?; - let n = &self.read_number_format_b(count)?; + let n = &self.read_signed_integer(count.into())?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } - _ => { - let n_value = self.demand_next(false)?; - let n = n_value.value().to_signedinteger()?; + Tag::SignedInteger => { + self.skip()?; + let count = self.varint()?; + let n = &self.read_signed_integer(count)?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } + _ => Err(self.expected(ExpectedKind::SignedInteger)) } } } impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { - type CompoundInfo = CompoundMinor; - fn next(&mut self, read_annotations: bool) -> IOResult> { match self.peek() { Err(e) if is_eof_io_error(&e) => return Ok(None), Err(e) => return Err(e), Ok(_) => (), } - loop { - return Ok(Some(match decodeop(self.read()?)? { - (Op::Misc(0), 0) => FALSE.clone(), - (Op::Misc(0), 1) => TRUE.clone(), - (Op::Misc(0), 2) => { - let mut bs = [0; 4]; - self.readbytes_into(&mut bs)?; - Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap() - } - (Op::Misc(0), 3) => { - let mut bs = [0; 8]; - self.readbytes_into(&mut bs)?; - Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap() - } - (Op::Misc(0), 5) => { - if read_annotations { - let mut annotations = vec![self.demand_next(read_annotations)?]; - while decodeop(self.peek()?)? == (Op::Misc(0), 5) { - self.skip()?; - annotations.push(self.demand_next(read_annotations)?); - } - let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces(); - annotations.extend_from_slice(existing_annotations.slice()); - IOValue::wrap(Annotations::new(Some(annotations)), v) - } else { - self.skip_value()?; - continue; + Ok(Some(match Tag::try_from(self.read()?)? { + Tag::False => FALSE.clone(), + Tag::True => TRUE.clone(), + Tag::Float => { + let mut bs = [0; 4]; + self.readbytes_into(&mut bs)?; + Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap() + } + Tag::Double => { + let mut bs = [0; 8]; + self.readbytes_into(&mut bs)?; + Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap() + } + Tag::Annotation => { + if read_annotations { + let mut annotations = vec![self.demand_next(read_annotations)?]; + while Tag::try_from(self.peek()?)? == Tag::Annotation { + self.skip()?; + annotations.push(self.demand_next(read_annotations)?); } - } - (Op::Misc(0), _) => Err(io_syntax_error("Invalid format A encoding"))?, - (Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?, - (Op::Misc(2), arg) => match Op::try_from(arg)? { - Op::Atom(minor) => - decodebinary(minor, Cow::Owned(self.gather_chunks()?))?, - Op::Compound(minor) => decodecompound(minor, DelimitedStream { - reader: self.configured(read_annotations), - })?, - _ => Err(io_syntax_error("Invalid format C start byte"))?, - } - (Op::Misc(3), arg) => { - let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) }; - // TODO: prebuild these in value.rs - Value::from(n).wrap() - } - (Op::Misc(_), _) => unreachable!(), - (Op::Atom(AtomMinor::SignedInteger), arg) => { - let count = self.wirelength(arg)?; - let n = self.read_number_format_b(count)?; - Value::SignedInteger(n).wrap() - } - (Op::Atom(minor), arg) => { - let count = self.wirelength(arg)?; - decodebinary(minor, self.readbytes(count)?)? - } - (Op::Compound(minor), arg) => { - let count = self.wirelength(arg)?; - decodecompound(minor, CountedStream { - reader: self.configured(read_annotations), - count, - })? - } - (Op::Reserved(3), 15) => continue, - (Op::Reserved(_), _) => return Err(InvalidOp.into()), - })) - } - } - - fn open_record(&mut self, arity: Option) -> ReaderResult> { - if let Some(expected_arity) = arity { - let compound_format = - self.next_compound(CompoundMinor::Record, ExpectedKind::Record(arity))?; - if let CompoundLimit::Counted(count) = compound_format.limit { - if count != expected_arity + 1 /* we add 1 for the label */ { - return Err(error::Error::Expected(ExpectedKind::Record(arity), - Received::ReceivedSomethingElse)); + let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces(); + annotations.extend_from_slice(existing_annotations.slice()); + IOValue::wrap(Annotations::new(Some(annotations)), v) + } else { + self.skip_value()?; + while Tag::try_from(self.peek()?)? == Tag::Annotation { + self.skip()?; + self.skip_value()?; + } + self.demand_next(read_annotations)? } } - Ok(compound_format) - } else { - self.next_compound(CompoundMinor::Record, ExpectedKind::Record(None)) - } + Tag::SmallInteger(v) => { + // TODO: prebuild these in value.rs + Value::from(v).wrap() + } + Tag::MediumInteger(count) => { + let n = self.read_signed_integer(count.into())?; + Value::SignedInteger(n).wrap() + } + Tag::SignedInteger => { + let count = self.varint()?; + let n = self.read_signed_integer(count)?; + Value::SignedInteger(n).wrap() + } + Tag::String => { + let count = self.varint()?; + Value::String(decodestr(self.readbytes(count)?)?.into_owned()).wrap() + } + Tag::ByteString => { + let count = self.varint()?; + Value::ByteString(self.readbytes(count)?.into_owned()).wrap() + } + Tag::Symbol => { + let count = self.varint()?; + Value::Symbol(decodestr(self.readbytes(count)?)?.into_owned()).wrap() + } + Tag::Record => { + let iter = DelimitedStream { reader: self.configured(read_annotations) }; + let vs = iter.collect::>>()?; + if vs.len() < 1 { + return Err(io_syntax_error("Too few elements in encoded record")) + } + Value::Record(Record(vs)).wrap() + } + Tag::Sequence => { + let iter = DelimitedStream { reader: self.configured(read_annotations) }; + let vs = iter.collect::>>()?; + Value::Sequence(vs).wrap() + } + Tag::Set => { + let iter = DelimitedStream { reader: self.configured(read_annotations) }; + let mut s = Set::new(); + for res in iter { s.insert(res?); } + Value::Set(s).wrap() + } + Tag::Dictionary => { + let mut iter = DelimitedStream { reader: self.configured(read_annotations) }; + let mut d = Map::new(); + while let Some(kres) = iter.next() { + let k = kres?; + match iter.next() { + Some(vres) => { + let v = vres?; + d.insert(k, v); + } + None => return Err(io_syntax_error("Missing dictionary value")), + } + } + Value::Dictionary(d).wrap() + } + tag @ Tag::End => { + return Err(io_syntax_error(&format!("Invalid tag: {:?}", tag))); + } + })) } - fn open_sequence_or_set(&mut self) -> ReaderResult> { - match self.peek_next_nonannotation_op()? { - (Op::Compound(minor), arg) - if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => { - self.skip()?; - Ok(CompoundBody::counted(minor, self.wirelength(arg)?)) - } - (Op::Misc(2), arg) => match Op::try_from(arg)? { - Op::Compound(minor) - if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => { - self.skip()?; - Ok(CompoundBody::streaming(minor)) - } - _ => Err(self.expected(ExpectedKind::SequenceOrSet)), + fn open_record(&mut self, arity: Option) -> ReaderResult<()> { + self.next_compound(Tag::Record, ExpectedKind::Record(arity))?; + self.ensure_more_expected() + } + + fn open_sequence_or_set(&mut self) -> ReaderResult<()> { + match self.peek_next_nonannotation_tag()? { + Tag::Sequence | Tag::Set => { + self.skip()?; + Ok(()) } _ => Err(self.expected(ExpectedKind::SequenceOrSet)), } } - fn open_sequence(&mut self) -> ReaderResult> { - self.next_compound(CompoundMinor::Sequence, ExpectedKind::Sequence) + fn open_sequence(&mut self) -> ReaderResult<()> { + self.next_compound(Tag::Sequence, ExpectedKind::Sequence) } - fn open_set(&mut self) -> ReaderResult> { - self.next_compound(CompoundMinor::Set, ExpectedKind::Set) + fn open_set(&mut self) -> ReaderResult<()> { + self.next_compound(Tag::Set, ExpectedKind::Set) } - fn open_dictionary(&mut self) -> ReaderResult> { - self.next_compound(CompoundMinor::Dictionary, ExpectedKind::Dictionary) + fn open_dictionary(&mut self) -> ReaderResult<()> { + self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary) } - fn close_compound_counted(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<()> { - // Nothing to do -- no close delimiter to consume - Ok(()) - } - - fn close_compound_stream(&mut self, _minor: Self::CompoundInfo) -> ReaderResult { + fn close_compound(&mut self) -> ReaderResult { Ok(self.peekend()?) } fn next_boolean(&mut self) -> ReaderResult { - match self.peek_next_nonannotation_op()? { - (Op::Misc(0), 0) => { self.skip()?; Ok(false) } - (Op::Misc(0), 1) => { self.skip()?; Ok(true) } + match self.peek_next_nonannotation_tag()? { + Tag::False => { self.skip()?; Ok(false) } + Tag::True => { self.skip()?; Ok(true) } _ => Err(self.expected(ExpectedKind::Boolean)), } } @@ -417,14 +379,14 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { fn next_u128(&mut self) -> ReaderResult { self.next_unsigned(|n| n.to_u128()) } fn next_float(&mut self) -> ReaderResult { - match self.peek_next_nonannotation_op()? { - (Op::Misc(0), 2) => { + match self.peek_next_nonannotation_tag()? { + Tag::Float => { self.skip()?; let mut bs = [0; 4]; self.readbytes_into(&mut bs)?; Ok(f32::from_bits(u32::from_be_bytes(bs))) }, - (Op::Misc(0), 3) => { + Tag::Double => { self.skip()?; let mut bs = [0; 8]; self.readbytes_into(&mut bs)?; @@ -435,14 +397,14 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { } fn next_double(&mut self) -> ReaderResult { - match self.peek_next_nonannotation_op()? { - (Op::Misc(0), 2) => { + match self.peek_next_nonannotation_tag()? { + Tag::Float => { self.skip()?; let mut bs = [0; 4]; self.readbytes_into(&mut bs)?; Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64) }, - (Op::Misc(0), 3) => { + Tag::Double => { self.skip()?; let mut bs = [0; 8]; self.readbytes_into(&mut bs)?; @@ -453,30 +415,15 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { } fn next_str(&mut self) -> ReaderResult> { - Ok(decodestr(self.next_atomic(AtomMinor::String, ExpectedKind::Symbol)?)?) + Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?) } fn next_bytestring(&mut self) -> ReaderResult> { - self.next_atomic(AtomMinor::ByteString, ExpectedKind::Symbol) + self.next_atomic(Tag::ByteString, ExpectedKind::Symbol) } fn next_symbol(&mut self) -> ReaderResult> { - Ok(decodestr(self.next_atomic(AtomMinor::Symbol, ExpectedKind::Symbol)?)?) - } -} - -struct CountedStream<'de, R: Reader<'de>> { - reader: ConfiguredReader<'de, R>, - count: usize, -} - -impl<'de, R: Reader<'de>> Iterator for CountedStream<'de, R> -{ - type Item = IOResult; - fn next(&mut self) -> Option { - if self.count == 0 { return None } - self.count -= 1; - Some(self.reader.reader.demand_next(self.reader.read_annotations)) + Ok(decodestr(self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?)?) } } @@ -496,11 +443,7 @@ impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S> } } -pub fn decodeop(b: u8) -> IOResult<(Op, u8)> { - Ok((Op::try_from(b >> 4)?, b & 15)) -} - -pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult> { +fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult> { match cow { Cow::Borrowed(bs) => Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)), @@ -508,53 +451,3 @@ pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult> { Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?.to_owned())), } } - -pub fn decodebinary<'de>(minor: AtomMinor, bs: Cow<'de, [u8]>) -> IOResult { - Ok(match minor { - AtomMinor::SignedInteger => Value::from(&BigInt::from_signed_bytes_be(&bs)).wrap(), - AtomMinor::String => Value::String(decodestr(bs)?.into_owned()).wrap(), - AtomMinor::ByteString => Value::ByteString(bs.into_owned()).wrap(), - AtomMinor::Symbol => Value::Symbol(decodestr(bs)?.into_owned()).wrap(), - }) -} - -pub fn decodecompound<'de, I: Iterator>>( - minor: CompoundMinor, - mut iter: I -) -> - IOResult -{ - match minor { - CompoundMinor::Record => { - let vs = iter.collect::>>()?; - if vs.len() < 1 { - Err(io_syntax_error("Too few elements in encoded record")) - } else { - Ok(Value::Record(Record(vs)).wrap()) - } - } - CompoundMinor::Sequence => { - let vs = iter.collect::>>()?; - Ok(Value::Sequence(vs).wrap()) - } - CompoundMinor::Set => { - let mut s = Set::new(); - for res in iter { s.insert(res?); } - Ok(Value::Set(s).wrap()) - } - CompoundMinor::Dictionary => { - let mut d = Map::new(); - while let Some(kres) = iter.next() { - let k = kres?; - match iter.next() { - Some(vres) => { - let v = vres?; - d.insert(k, v); - } - None => return Err(io_syntax_error("Missing dictionary value")), - } - } - Ok(Value::Dictionary(d).wrap()) - } - } -} diff --git a/implementations/rust/src/value/packed/writer.rs b/implementations/rust/src/value/packed/writer.rs index 01dceb8..ba29736 100644 --- a/implementations/rust/src/value/packed/writer.rs +++ b/implementations/rust/src/value/packed/writer.rs @@ -2,30 +2,275 @@ use num; use num::bigint::BigInt; use num::cast::ToPrimitive; use std::convert::TryInto; -use super::constants::{Op, AtomMinor, CompoundMinor}; +use std::mem; +use std::ops::{Deref, DerefMut}; +use super::constants::Tag; use super::super::IOValue; -use super::super::writer::{Writer, Result, varint}; +use super::super::writer::{Writer, AnnotationWriter, CompoundWriter, Result, varint}; -pub struct PackedWriter<'w, W: std::io::Write>(pub &'w mut W); - -pub fn write_op(w: &mut PackedWriter, op: Op, arg: u8) -> Result<()> { - w.0.write_all(&[(u8::from(op) << 4) | (arg & 15)]) +pub enum Suspendable { + Active(T), + Suspended, } -pub fn write_header(w: &mut PackedWriter, op: Op, wirelength: usize) -> Result<()> { - if wirelength < 15 { - write_op(w, op, wirelength as u8) - } else { - write_op(w, op, 15)?; - varint(w.0, wirelength as u64)?; +impl Suspendable { + pub fn new(t: T) -> Self { + Suspendable::Active(t) + } + + pub fn suspend(&mut self) -> Self { + match self { + Suspendable::Active(_) => mem::replace(self, Suspendable::Suspended), + Suspendable::Suspended => + panic!("Attempt to suspend suspended Suspendable"), + } + } + + pub fn resume(&mut self, other: Self) { + match self { + Suspendable::Suspended => + match other { + Suspendable::Active(_) => *self = other, + Suspendable::Suspended => + panic!("Attempt to resume from suspended Suspendable"), + }, + Suspendable::Active(_) => + panic!("Attempt to resume non-suspended Suspendable"), + } + } + + pub fn take(self) -> T { + match self { + Suspendable::Active(t) => t, + Suspendable::Suspended => + panic!("Attempt to take from suspended Suspendable"), + } + } +} + +impl Deref for Suspendable { + type Target = T; + fn deref(&self) -> &Self::Target { + match self { + Suspendable::Suspended => panic!("Suspended Suspendable at deref"), + Suspendable::Active(t) => t + } + } +} + +impl DerefMut for Suspendable { + fn deref_mut(&mut self) -> &mut Self::Target { + match self { + Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"), + Suspendable::Active(t) => t + } + } +} + +pub struct PackedWriter(Suspendable); + +impl PackedWriter> { + pub fn encode(v: &IOValue) -> std::io::Result> { + let mut buf: Vec = Vec::new(); + let w = &mut PackedWriter::new(&mut buf); + w.write(v)?; + Ok(buf) + } +} + +impl PackedWriter { + pub fn new(write: W) -> Self { + PackedWriter(Suspendable::new(write)) + } + + pub fn w(&mut self) -> &mut W { + self.0.deref_mut() + } + + pub fn write_byte(&mut self, b: u8) -> Result<()> { + self.w().write_all(&[b]) + } + + pub fn write_medium_integer(&mut self, bs: &[u8]) -> Result<()> { + let count: u8 = bs.len().try_into().unwrap(); + if count > 16 || count < 1 { panic!("Invalid medium_integer count: {}", count) } + self.write_byte(Tag::MediumInteger(count).into())?; + self.w().write_all(bs) + } + + pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> Result<()> { + self.write_byte(tag.into())?; + varint(&mut self.w(), bs.len().try_into().unwrap())?; + self.w().write_all(bs) + } + + pub fn suspend(&mut self) -> Self { + PackedWriter(self.0.suspend()) + } + + pub fn resume(&mut self, other: Self) { + self.0.resume(other.0) + } +} + +pub struct BinaryOrderWriter(Vec>); + +impl BinaryOrderWriter { + fn new() -> Self { + BinaryOrderWriter(vec![vec![]]) + } + + fn pop(&mut self) -> PackedWriter> { + PackedWriter::new(self.0.pop().unwrap()) + } + + fn push(&mut self, w: PackedWriter>) { + self.0.push(w.0.take()) + } + + fn items(&self) -> &Vec> { + &self.0 + } + + fn items_mut(&mut self) -> &mut Vec> { + &mut self.0 + } + + fn buffer(&mut self) -> &mut Vec { + self.0.last_mut().unwrap() + } + + fn finish(mut self, w: &mut W) -> Result<()> { + if self.buffer().len() != 0 { panic!("Missing final delimit()"); } + self.items_mut().pop(); + self.items_mut().sort(); + for bs in self.items() { + w.write_raw_bytes(&bs)?; + } + w.write_tag(Tag::End)?; Ok(()) } } -pub fn write_atom(w: &mut PackedWriter, minor: AtomMinor, bs: &[u8]) -> Result<()> { - write_header(w, Op::Atom(minor), bs.len())?; - w.0.write_all(bs) +pub trait WriteWriter: Writer { + fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()>; + fn write_tag(&mut self, tag: Tag) -> Result<()> { + self.write_raw_bytes(&[tag.into()]) + } +} + +impl WriteWriter for PackedWriter { + fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> { + self.w().write_all(v) + } +} + +impl WriteWriter for BinaryOrderWriter { + fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> { + use std::io::Write; + self.buffer().write_all(v) + } +} + +impl AnnotationWriter for T { + fn start_annotation(&mut self) -> Result<()> { + Ok(self.write_tag(Tag::Annotation)?) + } + + fn start_value(&mut self) -> Result<()> { + Ok(()) + } +} + +impl CompoundWriter for PackedWriter { + fn extend(&mut self) -> Result<()> { + Ok(()) + } + + fn delimit(&mut self) -> Result<()> { + Ok(()) + } +} + +impl CompoundWriter for BinaryOrderWriter { + fn extend(&mut self) -> Result<()> { + Ok(()) + } + + fn delimit(&mut self) -> Result<()> { + self.items_mut().push(vec![]); + Ok(()) + } +} + +macro_rules! binary_order_writer_method { + (mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) => + (fn $n (&mut self, $($argname : $argty),*) -> $retty { + (&mut PackedWriter::new(self.buffer())).$n($($argname),*) + }); +} + +impl Writer for BinaryOrderWriter { + type AnnWriter = PackedWriter>; + type SeqWriter = PackedWriter>; + type SetWriter = BinaryOrderWriter; + + binary_order_writer_method!(mut align(natural_chunksize: u64) -> Result<()>); + + fn start_annotations(&mut self) -> Result { + Ok(self.pop()) + } + fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> { + self.push(ann); + Ok(()) + } + + binary_order_writer_method!(mut write_bool(v: bool) -> Result<()>); + + binary_order_writer_method!(mut write_f32(v: f32) -> Result<()>); + binary_order_writer_method!(mut write_f64(v: f64) -> Result<()>); + + binary_order_writer_method!(mut write_i8(v: i8) -> Result<()>); + binary_order_writer_method!(mut write_u8(v: u8) -> Result<()>); + binary_order_writer_method!(mut write_i16(v: i16) -> Result<()>); + binary_order_writer_method!(mut write_u16(v: u16) -> Result<()>); + binary_order_writer_method!(mut write_i32(v: i32) -> Result<()>); + binary_order_writer_method!(mut write_u32(v: u32) -> Result<()>); + binary_order_writer_method!(mut write_i64(v: i64) -> Result<()>); + binary_order_writer_method!(mut write_u64(v: u64) -> Result<()>); + binary_order_writer_method!(mut write_i128(v: i128) -> Result<()>); + binary_order_writer_method!(mut write_u128(v: u128) -> Result<()>); + binary_order_writer_method!(mut write_int(v: &BigInt) -> Result<()>); + + binary_order_writer_method!(mut write_string(v: &str) -> Result<()>); + binary_order_writer_method!(mut write_bytes(v: &[u8]) -> Result<()>); + binary_order_writer_method!(mut write_symbol(v: &str) -> Result<()>); + + fn start_record(&mut self, _field_count: Option) -> Result { + self.write_tag(Tag::Record)?; + Ok(self.pop()) + } + fn start_sequence(&mut self, _item_count: Option) -> Result { + self.write_tag(Tag::Sequence)?; + Ok(self.pop()) + } + fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> { + self.push(seq); + self.write_tag(Tag::End) + } + + fn start_set(&mut self, _item_count: Option) -> Result { + self.write_tag(Tag::Set)?; + Ok(BinaryOrderWriter::new()) + } + fn start_dictionary(&mut self, _entry_count: Option) -> Result { + self.write_tag(Tag::Dictionary)?; + Ok(BinaryOrderWriter::new()) + } + fn end_set(&mut self, set: Self::SetWriter) -> Result<()> { + set.finish(self) + } } macro_rules! fits_in_bytes { @@ -35,38 +280,18 @@ macro_rules! fits_in_bytes { }) } -impl<'w, W: std::io::Write> PackedWriter<'w, W> { - pub fn write_noop(&mut self) -> Result<()> { - write_op(self, Op::Reserved(3), 15) - } -} +impl Writer for PackedWriter +{ + type AnnWriter = Self; + type SeqWriter = Self; + type SetWriter = BinaryOrderWriter; -impl<'w> PackedWriter<'w, &'w mut Vec> { - pub fn encode(v: &IOValue) -> std::io::Result> { - let mut buf: Vec = Vec::new(); - PackedWriter(&mut buf).write(v)?; - Ok(buf) - } -} - -impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> { - type Pointer = (); - type Annotation = (); - type Compound = bool; - type Dictionary = bool; - type StreamedAtom = (); - type KeyPointer = (); - - fn start_annotation(&mut self) -> Result { - Ok(()) + fn start_annotations(&mut self) -> Result { + Ok(self.suspend()) } - fn extend_annotation(&mut self, _a: &mut Self::Annotation, annotation: &IOValue) -> Result<()> { - write_header(self, Op::Misc(0), 5)?; - self.write(annotation) - } - - fn end_annotation(&mut self, _a: Self::Annotation, _value_p: Self::Pointer) -> Result { + fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> { + self.resume(ann); Ok(()) } @@ -75,235 +300,182 @@ impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> { } fn write_bool(&mut self, v: bool) -> Result<()> { - write_op(self, Op::Misc(0), if v { 1 } else { 0 }) + self.write_tag(if v { Tag::True } else { Tag::False }) } fn write_f32(&mut self, v: f32) -> Result<()> { - write_op(self, Op::Misc(0), 2)?; - self.0.write_all(&u32::to_be_bytes(f32::to_bits(v))) + self.write_tag(Tag::Float)?; + self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v))) } fn write_f64(&mut self, v: f64) -> Result<()> { - write_op(self, Op::Misc(0), 3)?; - self.0.write_all(&u64::to_be_bytes(f64::to_bits(v))) + self.write_tag(Tag::Double)?; + self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v))) } fn write_i8(&mut self, v: i8) -> Result<()> { - if v >= 0 && v <= 12 { return write_op(self, Op::Misc(3), v as u8) } - if v >= -3 && v < 0 { return write_op(self, Op::Misc(3), (v + 16) as u8) } - write_atom(self, AtomMinor::SignedInteger, &[v as u8]) + if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) } + self.write_medium_integer(&[v as u8]) } fn write_u8(&mut self, v: u8) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i8(w) } - write_atom(self, AtomMinor::SignedInteger, &[0, v]) + self.write_medium_integer(&[0, v]) } fn write_i16(&mut self, v: i16) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i8(w) } - write_atom(self, AtomMinor::SignedInteger, &[(v >> 8) as u8, (v & 255) as u8]) + self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8]) } fn write_u16(&mut self, v: u16) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i16(w) } - write_atom(self, AtomMinor::SignedInteger, &[0, (v >> 8) as u8, (v & 255) as u8]) + self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8]) } fn write_i32(&mut self, v: i32) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i16(w) } if fits_in_bytes!(v, 3) { - return write_atom(self, AtomMinor::SignedInteger, &[(v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + return self.write_medium_integer(&[(v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]); } - return write_atom(self, AtomMinor::SignedInteger, &[(v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + self.write_medium_integer(&[(v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]) } fn write_u32(&mut self, v: u32) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i32(w) } - return write_atom(self, AtomMinor::SignedInteger, &[0, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + self.write_medium_integer(&[0, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]) } fn write_i64(&mut self, v: i64) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i32(w) } if fits_in_bytes!(v, 5) { - return write_atom(self, AtomMinor::SignedInteger, &[(v >> 32) as u8, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + return self.write_medium_integer(&[(v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]); } if fits_in_bytes!(v, 6) { - return write_atom(self, AtomMinor::SignedInteger, &[(v >> 40) as u8, - (v >> 32) as u8, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + return self.write_medium_integer(&[(v >> 40) as u8, + (v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]); } if fits_in_bytes!(v, 7) { - return write_atom(self, AtomMinor::SignedInteger, &[(v >> 48) as u8, - (v >> 40) as u8, - (v >> 32) as u8, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + return self.write_medium_integer(&[(v >> 48) as u8, + (v >> 40) as u8, + (v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]); } - return write_atom(self, AtomMinor::SignedInteger, &[(v >> 56) as u8, - (v >> 48) as u8, - (v >> 40) as u8, - (v >> 32) as u8, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + self.write_medium_integer(&[(v >> 56) as u8, + (v >> 48) as u8, + (v >> 40) as u8, + (v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]) } fn write_u64(&mut self, v: u64) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i64(w) } - return write_atom(self, AtomMinor::SignedInteger, &[0, - (v >> 56) as u8, - (v >> 48) as u8, - (v >> 40) as u8, - (v >> 32) as u8, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - (v & 255) as u8]); + self.write_medium_integer(&[0, + (v >> 56) as u8, + (v >> 48) as u8, + (v >> 40) as u8, + (v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + (v & 255) as u8]) } fn write_i128(&mut self, v: i128) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i64(w) } let bs: [u8; 16] = v.to_be_bytes(); - if fits_in_bytes!(v, 9) { return write_atom(self, AtomMinor::SignedInteger, &bs[7..]); } - if fits_in_bytes!(v, 10) { return write_atom(self, AtomMinor::SignedInteger, &bs[6..]); } - if fits_in_bytes!(v, 11) { return write_atom(self, AtomMinor::SignedInteger, &bs[5..]); } - if fits_in_bytes!(v, 12) { return write_atom(self, AtomMinor::SignedInteger, &bs[4..]); } - if fits_in_bytes!(v, 13) { return write_atom(self, AtomMinor::SignedInteger, &bs[3..]); } - if fits_in_bytes!(v, 14) { return write_atom(self, AtomMinor::SignedInteger, &bs[2..]); } - if fits_in_bytes!(v, 15) { return write_atom(self, AtomMinor::SignedInteger, &bs[1..]); } - return write_atom(self, AtomMinor::SignedInteger, &bs); + if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); } + if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); } + if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); } + if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); } + if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); } + if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); } + if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); } + self.write_medium_integer(&bs) } fn write_u128(&mut self, v: u128) -> Result<()> { if let Ok(w) = v.try_into() { return self.write_i128(w) } let bs: [u8; 16] = v.to_be_bytes(); - write_header(self, Op::Atom(AtomMinor::SignedInteger), bs.len() + 1)?; - self.0.write_all(&[0])?; - self.0.write_all(&bs) + self.write_tag(Tag::SignedInteger)?; + varint(&mut self.w(), 17)?; + self.write_byte(0)?; + self.write_raw_bytes(&bs) } fn write_int(&mut self, v: &BigInt) -> Result<()> { match v.to_i8() { Some(n) => self.write_i8(n), - None => write_atom(self, AtomMinor::SignedInteger, &v.to_signed_bytes_be()), + None => { + match v.to_i128() { + Some(n) => self.write_i128(n), + None => self.write_atom(Tag::SignedInteger, &v.to_signed_bytes_be()), + } + } } } fn write_string(&mut self, v: &str) -> Result<()> { - write_atom(self, AtomMinor::String, v.as_bytes()) + self.write_atom(Tag::String, v.as_bytes()) } fn write_bytes(&mut self, v: &[u8]) -> Result<()> { - write_atom(self, AtomMinor::ByteString, v) + self.write_atom(Tag::ByteString, v) } fn write_symbol(&mut self, v: &str) -> Result<()> { - write_atom(self, AtomMinor::Symbol, v.as_bytes()) + self.write_atom(Tag::Symbol, v.as_bytes()) } - fn stream_string(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Atom(AtomMinor::String).into())?; - Ok(Some(())) + fn start_record(&mut self, _field_count: Option) -> Result { + self.write_tag(Tag::Record)?; + Ok(self.suspend()) } - fn stream_bytes(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Atom(AtomMinor::ByteString).into())?; - Ok(Some(())) + fn start_sequence(&mut self, _item_count: Option) -> Result { + self.write_tag(Tag::Sequence)?; + Ok(self.suspend()) } - fn stream_symbol(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Atom(AtomMinor::Symbol).into())?; - Ok(Some(())) + fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> { + self.resume(seq); + self.write_tag(Tag::End) } - fn extend_atom(&mut self, _s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()> { - self.write_bytes(bs) + fn start_set(&mut self, _item_count: Option) -> Result { + self.write_tag(Tag::Set)?; + Ok(BinaryOrderWriter::new()) } - fn end_atom(&mut self, _s: Self::StreamedAtom) -> Result<()> { - write_op(self, Op::Misc(0), 4) + fn start_dictionary(&mut self, _entry_count: Option) -> Result { + self.write_tag(Tag::Dictionary)?; + Ok(BinaryOrderWriter::new()) } - fn start_record(&mut self, field_count: usize) -> Result { - write_header(self, Op::Compound(CompoundMinor::Record), field_count + 1)?; - Ok(false) - } - - fn start_sequence(&mut self, item_count: usize) -> Result { - write_header(self, Op::Compound(CompoundMinor::Sequence), item_count)?; - Ok(false) - } - - fn start_set(&mut self, item_count: usize) -> Result { - write_header(self, Op::Compound(CompoundMinor::Set), item_count)?; - Ok(false) - } - - fn stream_record(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Record).into())?; - Ok(Some(true)) - } - - fn stream_sequence(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Sequence).into())?; - Ok(Some(true)) - } - - fn stream_set(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Set).into())?; - Ok(Some(true)) - } - - fn extend_compound(&mut self, _s: &mut Self::Compound, _value_p: Self::Pointer) -> Result<()> { - Ok(()) - } - - fn end_compound(&mut self, s: Self::Compound) -> Result<()> { - if s { - write_op(self, Op::Misc(0), 4) - } else { - Ok(()) - } - } - - fn start_dictionary(&mut self, entry_count: usize) -> Result { - write_header(self, Op::Compound(CompoundMinor::Dictionary), entry_count << 1)?; - Ok(false) - } - - fn stream_dictionary(&mut self) -> Result> { - write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Dictionary).into())?; - Ok(Some(true)) - } - - fn extend_dictionary_key(&mut self, _s: &mut Self::Dictionary, _key_p: Self::Pointer) -> Result { - Ok(()) - } - - fn extend_dictionary_value(&mut self, _s: &mut Self::Dictionary, _key_p: Self::KeyPointer, _value_p: Self::Pointer) -> Result<()> { - Ok(()) - } - - fn end_dictionary(&mut self, s: Self::Dictionary) -> Result<()> { - self.end_compound(s) + fn end_set(&mut self, set: Self::SetWriter) -> Result<()> { + set.finish(self) } } diff --git a/implementations/rust/src/value/reader.rs b/implementations/rust/src/value/reader.rs index 3e1fd99..a314002 100644 --- a/implementations/rust/src/value/reader.rs +++ b/implementations/rust/src/value/reader.rs @@ -8,16 +8,13 @@ pub type IOResult = std::result::Result; pub type ReaderResult = std::result::Result; pub trait Reader<'de> { - type CompoundInfo: Copy; - fn next(&mut self, read_annotations: bool) -> IOResult>; - fn open_record(&mut self, arity: Option) -> ReaderResult>; - fn open_sequence_or_set(&mut self) -> ReaderResult>; - fn open_sequence(&mut self) -> ReaderResult>; - fn open_set(&mut self) -> ReaderResult>; - fn open_dictionary(&mut self) -> ReaderResult>; - fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()>; - fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult; + fn open_record(&mut self, arity: Option) -> ReaderResult<()>; + fn open_sequence_or_set(&mut self) -> ReaderResult<()>; + fn open_sequence(&mut self) -> ReaderResult<()>; + fn open_set(&mut self) -> ReaderResult<()>; + fn open_dictionary(&mut self) -> ReaderResult<()>; + fn close_compound(&mut self) -> ReaderResult; //--------------------------------------------------------------------------- @@ -28,10 +25,7 @@ pub trait Reader<'de> { } fn demand_next(&mut self, read_annotations: bool) -> IOResult { - match self.next(read_annotations)? { - None => Err(io_eof()), - Some(v) => Ok(v) - } + self.next(read_annotations)?.ok_or_else(|| io_eof()) } fn next_boolean(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_boolean() } @@ -61,30 +55,24 @@ pub trait Reader<'de> { Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned())) } - fn open_option(&mut self) -> - ReaderResult<(bool, CompoundBody)> - where - Self: Sized + fn open_option(&mut self) -> ReaderResult { - let mut compound_body = self.open_record(None)?; - let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; + self.open_record(None)?; + let label: &str = &self.next_symbol()?; match label { - "None" => Ok((false, compound_body)), - "Some" => Ok((true, compound_body)), + "None" => Ok(false), + "Some" => Ok(true), _ => Err(error::Error::Expected(ExpectedKind::Option, Received::ReceivedRecordWithLabel(label.to_owned()))), } } - fn open_simple_record(&mut self, name: &str, arity: Option) -> - ReaderResult> - where - Self: Sized + fn open_simple_record(&mut self, name: &str, arity: Option) -> ReaderResult<()> { - let mut compound_body = self.open_record(arity)?; - let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; + self.open_record(arity)?; + let label: &str = &self.next_symbol()?; if label == name { - Ok(compound_body) + Ok(()) } else { Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity), Received::ReceivedRecordWithLabel(label.to_owned()))) @@ -101,129 +89,24 @@ pub trait Reader<'de> { phantom: PhantomData, } } -} -impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { - type CompoundInfo = R::CompoundInfo; - - fn next(&mut self, read_annotations: bool) -> IOResult> { - (*self).next(read_annotations) - } - - fn open_record(&mut self, arity: Option) -> ReaderResult> { - (*self).open_record(arity) - } - - fn open_sequence_or_set(&mut self) -> ReaderResult> { - (*self).open_sequence_or_set() - } - - fn open_sequence(&mut self) -> ReaderResult> { - (*self).open_sequence() - } - - fn open_set(&mut self) -> ReaderResult> { - (*self).open_set() - } - - fn open_dictionary(&mut self) -> ReaderResult> { - (*self).open_dictionary() - } - - fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()> { - (*self).close_compound_counted(info) - } - - fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult { - (*self).close_compound_stream(info) - } -} - -#[derive(Debug)] -pub struct CompoundBody { - pub info: I, - pub limit: CompoundLimit, -} - -#[derive(Debug)] -pub enum CompoundLimit { - Counted(usize), - Streaming, - Finished, -} - -impl CompoundBody { - pub fn counted(info: I, size: usize) -> Self { - CompoundBody { info, limit: CompoundLimit::Counted(size) } - } - - pub fn streaming(info: I) -> Self { - CompoundBody { info, limit: CompoundLimit::Streaming } - } - - pub fn more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult { - match self.limit { - CompoundLimit::Counted(ref mut n) => - if *n == 0 { - read.close_compound_counted(self.info)?; - self.limit = CompoundLimit::Finished; - Ok(false) - } else { - *n = *n - 1; - Ok(true) - }, - CompoundLimit::Streaming => - Ok(!read.close_compound_stream(self.info)?), - CompoundLimit::Finished => - Ok(false), - } - } - - pub fn next_symbol<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult>> { - match self.more_expected(read)? { - false => Ok(None), - true => Ok(Some(read.next_symbol()?)), - } - } - - pub fn next_value<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) -> - ReaderResult> - { - match self.more_expected(read)? { - false => Ok(None), - true => Ok(Some(read.demand_next(read_annotations)?)), - } - } - - pub fn remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) -> - ReaderResult> - { - let mut result = Vec::new(); - while let Some(v) = self.next_value(read, read_annotations)? { - result.push(v); - } - Ok(result) - } - - pub fn skip_remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> - ReaderResult<()> - { - while let true = self.more_expected(read)? { - read.skip_value()?; + fn skip_remainder(&mut self) -> ReaderResult<()> { + while !self.close_compound()? { + self.skip_value()?; } Ok(()) } - pub fn ensure_more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { - if self.more_expected(read)? { + fn ensure_more_expected(&mut self) -> ReaderResult<()> { + if !self.close_compound()? { Ok(()) } else { Err(error::Error::MissingItem) } } - pub fn ensure_complete<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { - if self.more_expected(read)? { + fn ensure_complete(&mut self) -> ReaderResult<()> { + if !self.close_compound()? { Err(error::Error::MissingCloseDelimiter) } else { Ok(()) @@ -231,6 +114,37 @@ impl CompoundBody { } } +impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { + fn next(&mut self, read_annotations: bool) -> IOResult> { + (*self).next(read_annotations) + } + + fn open_record(&mut self, arity: Option) -> ReaderResult<()> { + (*self).open_record(arity) + } + + fn open_sequence_or_set(&mut self) -> ReaderResult<()> { + (*self).open_sequence_or_set() + } + + fn open_sequence(&mut self) -> ReaderResult<()> { + (*self).open_sequence() + } + + fn open_set(&mut self) -> ReaderResult<()> { + (*self).open_set() + } + + fn open_dictionary(&mut self) -> ReaderResult<()> { + (*self).open_dictionary() + } + + fn close_compound(&mut self) -> ReaderResult { + (*self).close_compound() + } +} + + pub trait BinarySource<'de> { fn skip(&mut self) -> IOResult<()>; fn peek(&mut self) -> IOResult; diff --git a/implementations/rust/src/value/value.rs b/implementations/rust/src/value/value.rs index 43428de..a10f45e 100644 --- a/implementations/rust/src/value/value.rs +++ b/implementations/rust/src/value/value.rs @@ -236,16 +236,16 @@ impl, D: Domain> Debug for Value { // doesn't escape strings/symbols properly. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Value::Boolean(false) => f.write_str("#false"), - Value::Boolean(true) => f.write_str("#true"), + Value::Boolean(false) => f.write_str("#f"), + Value::Boolean(true) => f.write_str("#t"), Value::Float(Float(v)) => write!(f, "{:?}f", v), Value::Double(Double(v)) => write!(f, "{:?}", v), Value::SignedInteger(v) => write!(f, "{}", v), Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping! Value::ByteString(ref v) => { - f.write_str("#hex{")?; + f.write_str("#x\"")?; for b in v { write!(f, "{:02x}", b)? } - f.write_str("}") + f.write_str("\"") } Value::Symbol(ref v) => { // TODO: proper escaping! @@ -266,7 +266,7 @@ impl, D: Domain> Debug for Value { } Value::Sequence(ref v) => v.fmt(f), Value::Set(ref v) => { - f.write_str("#set")?; + f.write_str("#")?; f.debug_set().entries(v.iter()).finish() } Value::Dictionary(ref v) => f.debug_map().entries(v.iter()).finish(), @@ -849,7 +849,7 @@ impl, D: Domain> Annotations { } } -/// An possibly-annotated Value, with annotations (themselves +/// A possibly-annotated Value, with annotations (themselves /// possibly-annotated) in order of appearance. #[derive(Clone)] pub struct AnnotatedValue, D: Domain>(pub Annotations, pub Value); diff --git a/implementations/rust/src/value/writer.rs b/implementations/rust/src/value/writer.rs index d4673bf..7acf5b0 100644 --- a/implementations/rust/src/value/writer.rs +++ b/implementations/rust/src/value/writer.rs @@ -6,79 +6,77 @@ use super::value::{Domain, Value, NestedValue, IOValue, UnwrappedIOValue, Float, pub type Result = std::result::Result; -pub trait Writer { - type Pointer; - type Annotation; - type Compound; - type Dictionary; - type StreamedAtom; - type KeyPointer; +pub trait AnnotationWriter: Writer { + fn start_annotation(&mut self) -> Result<()>; + fn start_value(&mut self) -> Result<()>; +} + +pub trait CompoundWriter: Writer { + fn extend(&mut self) -> Result<()>; + fn delimit(&mut self) -> Result<()>; +} + +pub trait Writer: Sized { + type AnnWriter: AnnotationWriter; + type SeqWriter: CompoundWriter; + type SetWriter: CompoundWriter; fn align(&mut self, natural_chunksize: u64) -> Result<()>; - fn start_annotation(&mut self) -> Result; - fn extend_annotation(&mut self, a: &mut Self::Annotation, annotation: &IOValue) -> Result<()>; - fn end_annotation(&mut self, a: Self::Annotation, value_p: Self::Pointer) -> Result; + fn start_annotations(&mut self) -> Result; + fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()>; - fn write_bool(&mut self, v: bool) -> Result; + fn write_bool(&mut self, v: bool) -> Result<()>; - fn write_f32(&mut self, v: f32) -> Result; - fn write_f64(&mut self, v: f64) -> Result; + fn write_f32(&mut self, v: f32) -> Result<()>; + fn write_f64(&mut self, v: f64) -> Result<()>; - fn write_i8(&mut self, v: i8) -> Result; - fn write_u8(&mut self, v: u8) -> Result; - fn write_i16(&mut self, v: i16) -> Result; - fn write_u16(&mut self, v: u16) -> Result; - fn write_i32(&mut self, v: i32) -> Result; - fn write_u32(&mut self, v: u32) -> Result; - fn write_i64(&mut self, v: i64) -> Result; - fn write_u64(&mut self, v: u64) -> Result; - fn write_i128(&mut self, v: i128) -> Result; - fn write_u128(&mut self, v: u128) -> Result; - fn write_int(&mut self, v: &BigInt) -> Result; + fn write_i8(&mut self, v: i8) -> Result<()>; + fn write_u8(&mut self, v: u8) -> Result<()>; + fn write_i16(&mut self, v: i16) -> Result<()>; + fn write_u16(&mut self, v: u16) -> Result<()>; + fn write_i32(&mut self, v: i32) -> Result<()>; + fn write_u32(&mut self, v: u32) -> Result<()>; + fn write_i64(&mut self, v: i64) -> Result<()>; + fn write_u64(&mut self, v: u64) -> Result<()>; + fn write_i128(&mut self, v: i128) -> Result<()>; + fn write_u128(&mut self, v: u128) -> Result<()>; + fn write_int(&mut self, v: &BigInt) -> Result<()>; - fn write_string(&mut self, v: &str) -> Result; - fn write_bytes(&mut self, v: &[u8]) -> Result; - fn write_symbol(&mut self, v: &str) -> Result; + fn write_string(&mut self, v: &str) -> Result<()>; + fn write_bytes(&mut self, v: &[u8]) -> Result<()>; + fn write_symbol(&mut self, v: &str) -> Result<()>; - fn stream_string(&mut self) -> Result>; - fn stream_bytes(&mut self) -> Result>; - fn stream_symbol(&mut self) -> Result>; - fn extend_atom(&mut self, s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()>; - fn end_atom(&mut self, s: Self::StreamedAtom) -> Result; + fn start_record(&mut self, field_count: Option) -> Result; + fn start_sequence(&mut self, item_count: Option) -> Result; + fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()>; - fn start_record(&mut self, field_count: usize) -> Result; - fn start_sequence(&mut self, item_count: usize) -> Result; - fn start_set(&mut self, item_count: usize) -> Result; - fn stream_record(&mut self) -> Result>; - fn stream_sequence(&mut self) -> Result>; - fn stream_set(&mut self) -> Result>; - fn extend_compound(&mut self, s: &mut Self::Compound, value_p: Self::Pointer) -> Result<()>; - fn end_compound(&mut self, s: Self::Compound) -> Result; - - fn start_dictionary(&mut self, entry_count: usize) -> Result; - fn stream_dictionary(&mut self) -> Result>; - fn extend_dictionary_key(&mut self, s: &mut Self::Dictionary, key_p: Self::Pointer) -> Result; - fn extend_dictionary_value(&mut self, s: &mut Self::Dictionary, key_p: Self::KeyPointer, value_p: Self::Pointer) -> Result<()>; - fn end_dictionary(&mut self, s: Self::Dictionary) -> Result; + fn start_set(&mut self, item_count: Option) -> Result; + fn start_dictionary(&mut self, entry_count: Option) -> Result; + fn end_set(&mut self, set: Self::SetWriter) -> Result<()>; //--------------------------------------------------------------------------- - fn write(&mut self, v: &IOValue) -> Result { + fn write(&mut self, v: &IOValue) -> Result<()> { match v.annotations().maybe_slice() { - None => self.write_value(v.value()), + None => { + self.write_value(v.value())?; + } Some(anns) => { - let mut a = self.start_annotation()?; + let mut a = self.start_annotations()?; for ann in anns { - self.extend_annotation(&mut a, ann)?; + a.start_annotation()?; + a.write(ann)?; } - let p = self.write_value(v.value())?; - self.end_annotation(a, p) + a.start_value()?; + a.write_value(v.value())?; + self.end_annotations(a)?; } } + Ok(()) } - fn write_value(&mut self, v: &UnwrappedIOValue) -> Result { + fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<()> { match v { Value::Boolean(b) => self.write_bool(*b), Value::Float(Float(f)) => self.write_f32(*f), @@ -92,60 +90,50 @@ pub trait Writer { Value::ByteString(ref bs) => self.write_bytes(bs), Value::Symbol(ref s) => self.write_symbol(s), Value::Record(r) => { - let mut c = self.start_record(r.arity())?; - let p = self.write(r.label())?; - self.extend_compound(&mut c, p)?; + let mut c = self.start_record(Some(r.arity()))?; + c.extend()?; + c.write(r.label())?; + c.delimit()?; for f in r.fields() { - let p = self.write(f)?; - self.extend_compound(&mut c, p)?; + c.extend()?; + c.write(f)?; + c.delimit()?; } - self.end_compound(c) + self.end_seq(c) } Value::Sequence(ref vs) => { - let mut c = self.start_sequence(vs.len())?; + let mut c = self.start_sequence(Some(vs.len()))?; for v in vs { - let p = self.write(v)?; - self.extend_compound(&mut c, p)?; + c.extend()?; + c.write(v)?; + c.delimit()?; } - self.end_compound(c) + self.end_seq(c) } Value::Set(ref vs) => { - let mut c = self.start_set(vs.len())?; + let mut c = self.start_set(Some(vs.len()))?; for v in vs { - let p = self.write(v)?; - self.extend_compound(&mut c, p)?; + c.extend()?; + c.write(v)?; + c.delimit()?; } - self.end_compound(c) + self.end_set(c) } Value::Dictionary(ref vs) => { - let mut d = self.start_dictionary(vs.len())?; + let mut c = self.start_dictionary(Some(vs.len()))?; for (k, v) in vs { - let p = self.write(k)?; - let kp = self.extend_dictionary_key(&mut d, p)?; - let p = self.write(v)?; - self.extend_dictionary_value(&mut d, kp, p)?; + c.extend()?; + c.write(k)?; + c.write(v)?; + c.delimit()?; } - self.end_dictionary(d) + self.end_set(c) } Value::Domain(ref d) => self.write(&d.as_preserves()?) } } } -pub fn bigvarint(w: &mut W, mut v: u64) -> Result { - let mut byte_count = 0; - loop { - byte_count = byte_count + 4; - if v < (2 << 31) { - w.write_all(&(v as u32).to_le_bytes())?; - return Ok(byte_count); - } else { - w.write_all(&(((v & 0x7fffffff) + (2 << 31)) as u32).to_le_bytes())?; - v = v >> 31; - } - } -} - pub fn varint(w: &mut W, mut v: u64) -> Result { let mut byte_count = 0; loop { diff --git a/implementations/rust/tests/samples/mod.rs b/implementations/rust/tests/samples/mod.rs index 9272431..0507d8d 100644 --- a/implementations/rust/tests/samples/mod.rs +++ b/implementations/rust/tests/samples/mod.rs @@ -10,7 +10,6 @@ pub struct TestCases { pub enum TestCase { Test(#[serde(with = "serde_bytes")] Vec, IOValue), NondeterministicTest(#[serde(with = "serde_bytes")] Vec, IOValue), - StreamingTest(#[serde(with = "serde_bytes")] Vec, IOValue), DecodeTest(#[serde(with = "serde_bytes")] Vec, IOValue), ParseError(String), ParseShort(String), diff --git a/implementations/rust/tests/samples_tests.rs b/implementations/rust/tests/samples_tests.rs index 758abf4..45084b8 100644 --- a/implementations/rust/tests/samples_tests.rs +++ b/implementations/rust/tests/samples_tests.rs @@ -29,15 +29,11 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result, std::io::Error> { assert_eq!(&PackedWriter::encode(val)?, bin); } TestCase::NondeterministicTest(ref bin, ref val) => { - // The test cases in samples.txt are carefully - // written so that while strictly - // "nondeterministic", the order of keys in - // dictionaries follows Preserves order. - assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); - assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); + // The test cases in samples.txt are carefully written + // so that while strictly "nondeterministic", the + // order of keys in encoded dictionaries follows + // Preserves canonical order. assert_eq!(&PackedWriter::encode(val)?, bin); - } - TestCase::StreamingTest(ref bin, ref val) => { assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); }