diff --git a/implementations/rust/benches/codec.rs b/implementations/rust/benches/codec.rs index cce8825..94a395d 100644 --- a/implementations/rust/benches/codec.rs +++ b/implementations/rust/benches/codec.rs @@ -1,5 +1,5 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use preserves::value::{self, decoder, encoder, PackedReader, PackedWriter, reader::Reader}; +use preserves::value::{self, Reader, Writer, PackedReader, PackedWriter}; use preserves::{de, ser}; use std::io::Read; use std::io::BufReader; @@ -14,14 +14,14 @@ pub fn bench_decoder_bytes(c: &mut Criterion) { let mut bs = vec![]; fh.read_to_end(&mut bs).ok(); c.bench_function("decode samples.bin via bytes", |b| b.iter_with_large_drop( - || decoder::from_bytes(&bs[..]).demand_next().unwrap())); + || PackedReader::decode_bytes(&bs[..]).demand_next(true).unwrap())); } pub fn bench_decoder_file(c: &mut Criterion) { let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap(); c.bench_function("decode samples.bin via file", |b| b.iter_with_large_drop(|| { fh.seek(SeekFrom::Start(0)).ok(); - decoder::from_read(&mut fh).demand_next().unwrap() + PackedReader::decode_read(&mut fh).demand_next(true).unwrap() })); } @@ -29,16 +29,16 @@ pub fn bench_decoder_buffered_file(c: &mut Criterion) { let mut fh = BufReader::new(std::fs::File::open("../../tests/samples.bin").unwrap()); c.bench_function("decode samples.bin via buffered file", |b| b.iter_with_large_drop(|| { fh.seek(SeekFrom::Start(0)).ok(); - decoder::from_read(&mut fh).demand_next().unwrap() + PackedReader::decode_read(&mut fh).demand_next(true).unwrap() })); } pub fn bench_encoder(c: &mut Criterion) { let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap(); - let v = decoder::from_read(&mut fh).demand_next().unwrap(); + 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![]; - encoder::Encoder::new(&mut PackedWriter(&mut bs)).write(&v).unwrap(); + PackedWriter(&mut bs).write(&v).unwrap(); bs })); } @@ -66,7 +66,7 @@ pub fn bench_decoder_de(c: &mut Criterion) { let mut bs = vec![]; fh.read_to_end(&mut bs).ok(); c.bench_function("decode-then-deserialize samples.bin", |b| b.iter_with_large_drop( - || value::de::from_value::(&decoder::from_bytes(&bs[..]).demand_next().unwrap()).unwrap())); + || value::de::from_value::(&PackedReader::decode_bytes(&bs[..]).demand_next(true).unwrap()).unwrap())); } pub fn bench_ser_encoder(c: &mut Criterion) { @@ -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![]; - encoder::Encoder::new(&mut PackedWriter(&mut bs)).write(&value::ser::to_value(&v)).unwrap(); + PackedWriter(&mut bs).write(&value::ser::to_value(&v)).unwrap(); bs })); } @@ -85,7 +85,7 @@ pub fn large_testdata_decoder_with_ann(c: &mut Criterion) { let mut bs = vec![]; fh.read_to_end(&mut bs).ok(); b.iter(|| { - let mut r = PackedReader::from_bytes(&bs[..]); + let mut r = PackedReader::decode_bytes(&bs[..]); while let Some(_) = r.next(true).unwrap() {} }) }); @@ -97,7 +97,7 @@ pub fn large_testdata_decoder_without_ann(c: &mut Criterion) { let mut bs = vec![]; fh.read_to_end(&mut bs).ok(); b.iter(|| { - let mut r = PackedReader::from_bytes(&bs[..]); + let mut r = PackedReader::decode_bytes(&bs[..]); while let Some(_) = r.next(false).unwrap() {} }) }); @@ -107,16 +107,15 @@ pub fn large_testdata_encoder(c: &mut Criterion) { c.bench_function("encode testdata.bin", |b| { let mut fh = BufReader::new(std::fs::File::open("benches/testdata.bin").unwrap()); let mut vs = vec![]; - let mut r = PackedReader::from_read(&mut fh); + let mut r = PackedReader::decode_read(&mut fh); while let Some(v) = r.next(true).unwrap() { vs.push(v); } b.iter_with_large_drop(|| { let mut bs = vec![]; let mut w = PackedWriter(&mut bs); - let mut e = encoder::Encoder::new(&mut w); for v in &vs { - e.write(&v).unwrap(); + w.write(&v).unwrap(); } bs }) diff --git a/implementations/rust/examples/extensibility.rs b/implementations/rust/examples/extensibility.rs index 6e3aae6..7ee10df 100644 --- a/implementations/rust/examples/extensibility.rs +++ b/implementations/rust/examples/extensibility.rs @@ -1,4 +1,4 @@ -use preserves::{de, value, value::decoder}; +use preserves::{de, value::{self, Reader, PackedReader}}; use serde::{Serialize, Deserialize}; use std::fs::File; use std::io::Error; @@ -33,7 +33,7 @@ enum Variety { } fn try_file(kind: &str, path: &str) -> Result<(), Error> { - let fruits_value = decoder::from_read(&mut File::open(path)?).demand_next()?; + let fruits_value = PackedReader::decode_read(&mut File::open(path)?).demand_next(true)?; println!("{:?}", fruits_value); let fruits1: Vec = value::de::from_value(&fruits_value)?; diff --git a/implementations/rust/src/lib.rs b/implementations/rust/src/lib.rs index 25bce45..5ea8084 100644 --- a/implementations/rust/src/lib.rs +++ b/implementations/rust/src/lib.rs @@ -12,7 +12,7 @@ pub mod value; mod dom { use super::value::{ Value, IOValue, NestedValue, PlainValue, Domain, - encoder::encode_bytes, + PackedWriter, }; #[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)] @@ -36,7 +36,7 @@ mod dom { Value::Domain(Dom::One).wrap(), Value::from(2).wrap()]) .wrap(); - assert_eq!(encode_bytes(&v.to_io_value()).unwrap(), + assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(), [147, 49, 100, 255, 255, 255, 255, 50]); } @@ -45,7 +45,7 @@ mod dom { Value::Domain(Dom::Two).wrap(), Value::from(2).wrap()]) .wrap(); - assert_eq!(encode_bytes(&v.to_io_value()).unwrap(), + assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(), [147, 49, 120, 68, 111, 109, 58, 58, 84, 119, 111, 50]); } } @@ -229,7 +229,7 @@ mod value_tests { #[cfg(test)] mod decoder_tests { - use crate::value::{Value, NestedValue, decoder}; + use crate::value::{Value, NestedValue, PackedReader, ConfiguredReader}; use crate::de::from_bytes; use crate::error::{Error, ExpectedKind, is_eof_io_error}; @@ -251,7 +251,7 @@ mod decoder_tests { #[test] fn skip_annotations_noskip() { let mut buf = &b"\x0521"[..]; - let mut d = decoder::from_bytes(&mut buf); + let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); let v = d.demand_next().unwrap(); assert_eq!(v.annotations().slice().len(), 1); assert_eq!(v.annotations().slice()[0], Value::from(2).wrap()); @@ -260,7 +260,7 @@ mod decoder_tests { #[test] fn skip_annotations_skip() { let mut buf = &b"\x0521"[..]; - let mut d = decoder::from_bytes(&mut buf); + let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); d.set_read_annotations(false); let v = d.demand_next().unwrap(); assert_eq!(v.annotations().slice().len(), 0); @@ -270,12 +270,12 @@ mod decoder_tests { #[test] fn multiple_values_buf_advanced() { let mut buf = &b"\x81tPing\x81tPong"[..]; assert_eq!(buf.len(), 12); - let mut d = decoder::from_bytes(&mut buf); - assert_eq!(d.read.source.index, 0); + 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.read.source.index, 6); + assert_eq!(d.reader.source.index, 6); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong")); - assert_eq!(d.read.source.index, 12); + assert_eq!(d.reader.source.index, 12); assert!(d.next().is_none()); assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false }); } @@ -387,7 +387,6 @@ mod serde_tests { use crate::symbol::Symbol; use crate::de::from_bytes as deserialize_from_bytes; use crate::value::de::from_value as deserialize_from_value; - use crate::value::encoder::encode_bytes; use crate::value::to_value; use crate::value::{Value, IOValue, Map, Set}; use crate::value::packed::PackedWriter; @@ -476,7 +475,7 @@ mod serde_tests { 0x3, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789 ]; - let v_bytes_1 = encode_bytes(&w).unwrap(); + let v_bytes_1 = PackedWriter::encode(&w).unwrap(); println!("== w bytes = {:?}", v_bytes_1); assert_eq!(expected_bytes, v_bytes_1); diff --git a/implementations/rust/src/ser.rs b/implementations/rust/src/ser.rs index c03ec73..1e728bc 100644 --- a/implementations/rust/src/ser.rs +++ b/implementations/rust/src/ser.rs @@ -1,6 +1,5 @@ use serde::Serialize; use super::value::writer::Writer; -use super::value::Encoder; pub use super::error::Error; type Result = std::result::Result; @@ -148,7 +147,7 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { { match super::value::magic::receive_output_value(name, value) { Some(v) => { - Ok(Encoder::new(self.write).write(&v)?) + Ok(self.write.write(&v)?) } None => { // TODO: This is apparently discouraged, and we should apparently just serialize `value`? diff --git a/implementations/rust/src/value/decoder.rs b/implementations/rust/src/value/decoder.rs deleted file mode 100644 index 6d34b6e..0000000 --- a/implementations/rust/src/value/decoder.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::marker::PhantomData; -use super::packed::PackedReader; -use super::reader::{self, Reader}; -use super::value::IOValue; - -pub use super::reader::IOResult as Result; - -pub struct Decoder<'de, R: Reader<'de>> { - pub read: R, - read_annotations: bool, - phantom: PhantomData<&'de ()>, -} - -pub fn from_bytes<'de>(bytes: &'de [u8]) -> - Decoder<'de, PackedReader<'de, reader::BytesBinarySource<'de>>> -{ - Decoder::new(PackedReader::from_bytes(bytes)) -} - -pub fn from_read<'de, 'a, IOR: std::io::Read>(read: &'a mut IOR) -> - Decoder<'de, PackedReader<'de, reader::IOBinarySource<'a, IOR>>> -{ - Decoder::new(PackedReader::from_read(read)) -} - -impl<'de, R: Reader<'de>> Decoder<'de, R> { - pub fn new(read: R) -> Self { - Decoder { read, read_annotations: true, phantom: PhantomData } - } - - pub fn set_read_annotations(&mut self, read_annotations: bool) { - self.read_annotations = read_annotations - } - - pub fn demand_next(&mut self) -> Result { - self.read.demand_next(self.read_annotations) - } -} - -impl<'de, R: Reader<'de>> std::iter::Iterator for Decoder<'de, R> { - type Item = Result; - fn next(&mut self) -> Option { - match self.read.next(self.read_annotations) { - Err(e) => Some(Err(e)), - Ok(None) => None, - Ok(Some(v)) => Some(Ok(v)), - } - } -} diff --git a/implementations/rust/src/value/encoder.rs b/implementations/rust/src/value/encoder.rs deleted file mode 100644 index 52d0ab4..0000000 --- a/implementations/rust/src/value/encoder.rs +++ /dev/null @@ -1,89 +0,0 @@ -use super::value::{Value, NestedValue, Domain, IOValue, UnwrappedIOValue, Float, Double}; -use super::signed_integer::SignedIntegerRepr; -use super::writer::Writer; -use super::packed::PackedWriter; - -pub use super::writer::Result; - -pub struct Encoder<'a, W: Writer> { - pub write: &'a mut W, -} - -pub fn encode_bytes(v: &IOValue) -> std::io::Result> { - let mut buf: Vec = Vec::new(); - Encoder::new(&mut PackedWriter(&mut buf)).write(v)?; - Ok(buf) -} - -impl<'a, W: Writer> Encoder<'a, W> { - pub fn new(write: &'a mut W) -> Self { - Encoder { write } - } - - pub fn write(&mut self, v: &IOValue) -> Result { - match v.annotations().maybe_slice() { - None => self.write_value(v.value()), - Some(anns) => { - let mut a = self.write.start_annotation()?; - for ann in anns { - self.write.extend_annotation(&mut a, ann)?; - } - let p = self.write_value(v.value())?; - self.write.end_annotation(a, p) - } - } - } - - pub fn write_value(&mut self, v: &UnwrappedIOValue) -> Result { - match v { - Value::Boolean(b) => self.write.write_bool(*b), - Value::Float(Float(f)) => self.write.write_f32(*f), - Value::Double(Double(d)) => self.write.write_f64(*d), - Value::SignedInteger(n) => match n.repr() { - SignedIntegerRepr::I128(i) => self.write.write_i128(*i), - SignedIntegerRepr::U128(u) => self.write.write_u128(*u), - SignedIntegerRepr::Big(ref n) => self.write.write_int(n), - } - Value::String(ref s) => self.write.write_string(s), - Value::ByteString(ref bs) => self.write.write_bytes(bs), - Value::Symbol(ref s) => self.write.write_symbol(s), - Value::Record(r) => { - let mut c = self.write.start_record(r.arity() as u64)?; - let p = self.write(r.label())?; - self.write.extend_compound(&mut c, p)?; - for f in r.fields() { - let p = self.write(f)?; - self.write.extend_compound(&mut c, p)?; - } - self.write.end_compound(c) - } - Value::Sequence(ref vs) => { - let mut c = self.write.start_sequence(vs.len() as u64)?; - for v in vs { - let p = self.write(v)?; - self.write.extend_compound(&mut c, p)?; - } - self.write.end_compound(c) - } - Value::Set(ref vs) => { - let mut c = self.write.start_set(vs.len() as u64)?; - for v in vs { - let p = self.write(v)?; - self.write.extend_compound(&mut c, p)?; - } - self.write.end_compound(c) - } - Value::Dictionary(ref vs) => { - let mut d = self.write.start_dictionary(vs.len() as u64)?; - for (k, v) in vs { - let p = self.write(k)?; - let kp = self.write.extend_dictionary_key(&mut d, p)?; - let p = self.write(v)?; - self.write.extend_dictionary_value(&mut d, kp, p)?; - } - self.write.end_dictionary(d) - } - Value::Domain(ref d) => self.write(&d.as_preserves()?) - } - } -} diff --git a/implementations/rust/src/value/mod.rs b/implementations/rust/src/value/mod.rs index a93086f..97469a6 100644 --- a/implementations/rust/src/value/mod.rs +++ b/implementations/rust/src/value/mod.rs @@ -1,6 +1,4 @@ pub mod de; -pub mod decoder; -pub mod encoder; pub mod magic; pub mod packed; pub mod reader; @@ -11,10 +9,9 @@ pub mod writer; pub use de::Deserializer; pub use de::from_value; -pub use decoder::Decoder; -pub use encoder::Encoder; pub use packed::PackedReader; pub use packed::PackedWriter; +pub use reader::ConfiguredReader; pub use reader::Reader; pub use ser::Serializer; pub use ser::to_value; diff --git a/implementations/rust/src/value/packed/reader.rs b/implementations/rust/src/value/packed/reader.rs index 6f43d53..58cf828 100644 --- a/implementations/rust/src/value/packed/reader.rs +++ b/implementations/rust/src/value/packed/reader.rs @@ -3,7 +3,6 @@ use num::traits::cast::{FromPrimitive, ToPrimitive}; use std::borrow::Cow; use std::convert::TryFrom; use std::convert::TryInto; -// use std::io::{Read, Error}; use std::marker::PhantomData; use super::super::signed_integer::SignedInteger; use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations}; @@ -14,6 +13,7 @@ use super::super::reader::{ BytesBinarySource, CompoundBody, CompoundLimit, + ConfiguredReader, IOBinarySource, IOResult, Reader, @@ -47,13 +47,13 @@ fn out_of_range>(i: I) -> error::Error { } impl<'de> PackedReader<'de, BytesBinarySource<'de>> { - pub fn from_bytes(bytes: &'de [u8]) -> Self { + pub fn decode_bytes(bytes: &'de [u8]) -> Self { PackedReader::new(BytesBinarySource::new(bytes)) } } impl<'de, 'a, IOR: std::io::Read> PackedReader<'de, IOBinarySource<'a, IOR>> { - pub fn from_read(read: &'a mut IOR) -> Self { + pub fn decode_read(read: &'a mut IOR) -> Self { PackedReader::new(IOBinarySource::new(read)) } } @@ -308,11 +308,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { Op::Atom(minor) => decodebinary(minor, Cow::Owned(self.gather_chunks()?))?, Op::Compound(minor) => decodecompound(minor, DelimitedStream { - reader: ConfiguredPackedReader { - reader: self, - read_annotations, - phantom: PhantomData, - }, + reader: self.configured(read_annotations), })?, _ => Err(io_syntax_error("Invalid format C start byte"))?, } @@ -334,11 +330,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { (Op::Compound(minor), arg) => { let count = self.wirelength(arg)?; decodecompound(minor, CountedStream { - reader: ConfiguredPackedReader { - reader: self, - read_annotations, - phantom: PhantomData, - }, + reader: self.configured(read_annotations), count, })? } @@ -473,18 +465,12 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { } } -struct ConfiguredPackedReader<'de, 'a, S: BinarySource<'de>> { - reader: &'a mut PackedReader<'de, S>, - read_annotations: bool, - phantom: PhantomData<&'de ()>, -} - -struct CountedStream<'de, 'a, S: BinarySource<'de>> { - reader: ConfiguredPackedReader<'de, 'a, S>, +struct CountedStream<'de, R: Reader<'de>> { + reader: ConfiguredReader<'de, R>, count: usize, } -impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S> +impl<'de, R: Reader<'de>> Iterator for CountedStream<'de, R> { type Item = IOResult; fn next(&mut self) -> Option { @@ -494,11 +480,11 @@ impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S> } } -struct DelimitedStream<'de, 'a, S: BinarySource<'de>> { - reader: ConfiguredPackedReader<'de, 'a, S>, +struct DelimitedStream<'a, 'de, S: BinarySource<'de>> { + reader: ConfiguredReader<'de, &'a mut PackedReader<'de, S>>, } -impl<'de, 'a, S: BinarySource<'de>> Iterator for DelimitedStream<'de, 'a, S> +impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S> { type Item = IOResult; fn next(&mut self) -> Option { diff --git a/implementations/rust/src/value/packed/writer.rs b/implementations/rust/src/value/packed/writer.rs index 4d6797b..527c8e2 100644 --- a/implementations/rust/src/value/packed/writer.rs +++ b/implementations/rust/src/value/packed/writer.rs @@ -3,7 +3,7 @@ use num::bigint::BigInt; use num::cast::ToPrimitive; use std::convert::TryInto; use super::constants::{Op, AtomMinor, CompoundMinor}; -use super::super::{Encoder, IOValue}; +use super::super::IOValue; use super::super::writer::{Writer, Result, varint}; @@ -40,6 +40,14 @@ impl<'w, W: std::io::Write> PackedWriter<'w, W> { } } +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 = (); @@ -58,7 +66,7 @@ impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> { fn extend_annotation(&mut self, _a: &mut Self::Annotation, annotation: &IOValue) -> Result<()> { write_header(self, Op::Misc(0), 5)?; - Encoder::new(self).write(annotation) + self.write(annotation) } fn end_annotation(&mut self, _a: Self::Annotation, _value_p: Self::Pointer) -> Result { diff --git a/implementations/rust/src/value/reader.rs b/implementations/rust/src/value/reader.rs index 460afff..3e1fd99 100644 --- a/implementations/rust/src/value/reader.rs +++ b/implementations/rust/src/value/reader.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::io::{Read, Error}; +use std::marker::PhantomData; use super::value::{NestedValue, IOValue}; use crate::error::{self, ExpectedKind, Received, io_eof}; @@ -89,6 +90,17 @@ pub trait Reader<'de> { Received::ReceivedRecordWithLabel(label.to_owned()))) } } + + fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, Self> + where + Self: std::marker::Sized + { + ConfiguredReader { + reader: self, + read_annotations, + phantom: PhantomData, + } + } } impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { @@ -321,3 +333,34 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> { } } } + +pub struct ConfiguredReader<'de, R: Reader<'de>> { + pub reader: R, + pub read_annotations: bool, + phantom: PhantomData<&'de ()>, +} + +impl<'de, R: Reader<'de>> ConfiguredReader<'de, R> { + pub fn new(reader: R) -> Self { + reader.configured(true) + } + + pub fn set_read_annotations(&mut self, read_annotations: bool) { + self.read_annotations = read_annotations + } + + pub fn demand_next(&mut self) -> IOResult { + self.reader.demand_next(self.read_annotations) + } +} + +impl<'de, R: Reader<'de>> std::iter::Iterator for ConfiguredReader<'de, R> { + type Item = IOResult; + fn next(&mut self) -> Option { + match self.reader.next(self.read_annotations) { + Err(e) => Some(Err(e)), + Ok(None) => None, + Ok(Some(v)) => Some(Ok(v)), + } + } +} diff --git a/implementations/rust/src/value/writer.rs b/implementations/rust/src/value/writer.rs index 6ce7bd6..d901b2e 100644 --- a/implementations/rust/src/value/writer.rs +++ b/implementations/rust/src/value/writer.rs @@ -1,7 +1,8 @@ use num; use num::bigint::BigInt; use std::io::Error; -use super::value::IOValue; +use super::signed_integer::SignedIntegerRepr; +use super::value::{Domain, Value, NestedValue, IOValue, UnwrappedIOValue, Float, Double}; pub type Result = std::result::Result; @@ -62,6 +63,75 @@ pub trait Writer { 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 write(&mut self, v: &IOValue) -> Result { + match v.annotations().maybe_slice() { + None => self.write_value(v.value()), + Some(anns) => { + let mut a = self.start_annotation()?; + for ann in anns { + self.extend_annotation(&mut a, ann)?; + } + let p = self.write_value(v.value())?; + self.end_annotation(a, p) + } + } + } + + 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), + Value::Double(Double(d)) => self.write_f64(*d), + Value::SignedInteger(n) => match n.repr() { + SignedIntegerRepr::I128(i) => self.write_i128(*i), + SignedIntegerRepr::U128(u) => self.write_u128(*u), + SignedIntegerRepr::Big(ref n) => self.write_int(n), + } + Value::String(ref s) => self.write_string(s), + 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() as u64)?; + let p = self.write(r.label())?; + self.extend_compound(&mut c, p)?; + for f in r.fields() { + let p = self.write(f)?; + self.extend_compound(&mut c, p)?; + } + self.end_compound(c) + } + Value::Sequence(ref vs) => { + let mut c = self.start_sequence(vs.len() as u64)?; + for v in vs { + let p = self.write(v)?; + self.extend_compound(&mut c, p)?; + } + self.end_compound(c) + } + Value::Set(ref vs) => { + let mut c = self.start_set(vs.len() as u64)?; + for v in vs { + let p = self.write(v)?; + self.extend_compound(&mut c, p)?; + } + self.end_compound(c) + } + Value::Dictionary(ref vs) => { + let mut d = self.start_dictionary(vs.len() as u64)?; + 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)?; + } + self.end_dictionary(d) + } + Value::Domain(ref d) => self.write(&d.as_preserves()?) + } + } } pub fn bigvarint(w: &mut W, mut v: u64) -> Result<()> { diff --git a/implementations/rust/tests/samples_tests.rs b/implementations/rust/tests/samples_tests.rs index dfca6c4..758abf4 100644 --- a/implementations/rust/tests/samples_tests.rs +++ b/implementations/rust/tests/samples_tests.rs @@ -1,22 +1,22 @@ use preserves::error::{is_eof_io_error, is_syntax_io_error}; use preserves::symbol::Symbol; -use preserves::value::de::from_value as deserialize_from_value; -use preserves::value::decoder; -use preserves::value::encoder::encode_bytes; use preserves::value::IOValue; +use preserves::value::PackedReader; +use preserves::value::PackedWriter; +use preserves::value::Reader; +use preserves::value::de::from_value as deserialize_from_value; use std::iter::Iterator; mod samples; use samples::*; fn decode_all<'de>(bytes: &'de [u8]) -> Result, std::io::Error> { - let d = decoder::from_bytes(bytes); - d.collect() + PackedReader::decode_bytes(bytes).configured(true).collect() } #[test] fn run() -> std::io::Result<()> { let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap(); - let mut d = decoder::from_read(&mut fh); + let mut d = PackedReader::decode_read(&mut fh).configured(true); let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap(); // println!("{:#?}", tests); @@ -24,25 +24,25 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result, std::io::Error> { println!("{:?} ==> {:?}", name, case); match case { TestCase::Test(ref bin, ref val) => { - assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]); + assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); - assert_eq!(&encode_bytes(val)?, bin); + 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(&encode_bytes(val)?[..])?, &[val.clone()]); + assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); - assert_eq!(&encode_bytes(val)?, bin); + assert_eq!(&PackedWriter::encode(val)?, bin); } TestCase::StreamingTest(ref bin, ref val) => { - assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]); + assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); } TestCase::DecodeTest(ref bin, ref val) => { - assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]); + assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); } TestCase::ParseError(_) => (), @@ -59,14 +59,14 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result, std::io::Error> { } } TestCase::DecodeShort(ref bin) => { - assert!(if let Err(e) = decoder::from_bytes(bin).next().unwrap() { + assert!(if let Err(e) = PackedReader::decode_bytes(bin).configured(true).next().unwrap() { is_eof_io_error(&e) } else { false }) } TestCase::DecodeEOF(ref bin) => { - assert!(decoder::from_bytes(bin).next().is_none()); + assert!(PackedReader::decode_bytes(bin).configured(true).next().is_none()); } } }