From 755a8bc73b759ed1a2641f5751e19720af8d0dd4 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 29 Oct 2023 21:00:56 +0100 Subject: [PATCH] Enable parse tests in rust --- .../rust/preserves/src/value/reader.rs | 2 +- .../rust/preserves/src/value/text/reader.rs | 50 ++++++++----------- .../rust/preserves/tests/samples_tests.rs | 49 +++++++++++++++--- 3 files changed, 62 insertions(+), 39 deletions(-) diff --git a/implementations/rust/preserves/src/value/reader.rs b/implementations/rust/preserves/src/value/reader.rs index 1900e66..e60a4f6 100644 --- a/implementations/rust/preserves/src/value/reader.rs +++ b/implementations/rust/preserves/src/value/reader.rs @@ -373,7 +373,7 @@ pub trait BinarySource<'de>: Sized { fn text>( &mut self, decode_embedded: Dec, - ) -> super::TextReader<'de, '_, N::Embedded, Dec, Self> { + ) -> super::TextReader<'de, '_, N, Dec, Self> { super::TextReader::new(self, decode_embedded) } diff --git a/implementations/rust/preserves/src/value/text/reader.rs b/implementations/rust/preserves/src/value/text/reader.rs index 9c10e03..a9b3533 100644 --- a/implementations/rust/preserves/src/value/text/reader.rs +++ b/implementations/rust/preserves/src/value/text/reader.rs @@ -15,8 +15,6 @@ use crate::value::reader::ReaderResult; use crate::value::repr::Annotations; use crate::value::CompoundClass; use crate::value::DomainParse; -use crate::value::DummyValue; -use crate::value::Embeddable; use crate::value::IOValue; use crate::value::IOValueDomainCodec; use crate::value::Map; @@ -34,16 +32,15 @@ use num::bigint::BigInt; use std::convert::TryInto; use std::io; -use std::iter::FromIterator; use std::marker::PhantomData; /// The text syntax Preserves reader. -pub struct TextReader<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> { +pub struct TextReader<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<'de>> { /// Underlying source of (utf8) bytes. pub source: &'src mut S, /// Decoder for producing Rust values embedded in the text. pub dec: Dec, - phantom: PhantomData<&'de D>, + phantom: PhantomData<&'de N>, } fn decode_utf8(bs: Vec) -> io::Result { @@ -58,8 +55,8 @@ fn append_codepoint(bs: &mut Vec, n: u32) -> io::Result<()> { Ok(()) } -impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> - TextReader<'de, 'src, D, Dec, S> +impl<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<'de>> + TextReader<'de, 'src, N, Dec, S> { /// Construct a new reader from a byte (utf8) source and embedded-value decoder. pub fn new(source: &'src mut S, dec: Dec) -> Self { @@ -98,14 +95,14 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } // TODO: This is a duplicate of fn expected in PackedReader. - fn expected>(&mut self, k: ExpectedKind) -> Error { + fn expected(&mut self, k: ExpectedKind) -> Error { match Reader::::demand_next(self, true) { Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))), Err(e) => e.into(), } } - fn gather_annotations>(&mut self) -> ReaderResult> { + fn gather_annotations(&mut self) -> ReaderResult> { let mut vs = Vec::new(); loop { self.skip_whitespace(); @@ -133,7 +130,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } b'@' => { self.skip()?; - Reader::>::skip_value(self)?; + self.skip_value()?; } _ => return Ok(()), } @@ -159,7 +156,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } } - fn read_hex_float(&mut self, bytecount: usize) -> io::Result { + fn read_hex_float(&mut self, bytecount: usize) -> io::Result { if self.next_byte()? != b'"' { return Err(io_syntax_error( "Missing open-double-quote in hex-encoded floating-point number", @@ -252,7 +249,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> )?) } - fn read_literal_binary(&mut self) -> io::Result { + fn read_literal_binary(&mut self) -> io::Result { Ok(N::new( &self.read_stringlike( Vec::new(), @@ -281,7 +278,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } } - fn read_base64_binary(&mut self) -> io::Result { + fn read_base64_binary(&mut self) -> io::Result { let mut bs = Vec::new(); loop { self.skip_whitespace(); @@ -304,11 +301,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } } - fn upto>( - &mut self, - delimiter: u8, - read_annotations: bool, - ) -> io::Result> { + fn upto(&mut self, delimiter: u8, read_annotations: bool) -> io::Result> { let mut vs = Vec::new(); loop { self.skip_whitespace(); @@ -320,10 +313,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } } - fn read_dictionary>( - &mut self, - read_annotations: bool, - ) -> io::Result { + fn read_dictionary(&mut self, read_annotations: bool) -> io::Result { let mut d = Map::new(); loop { self.skip_whitespace(); @@ -341,7 +331,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } } - fn read_raw_symbol_or_number(&mut self, mut bs: Vec) -> io::Result { + fn read_raw_symbol_or_number(&mut self, mut bs: Vec) -> io::Result { lazy_static! { static ref NUMBER_RE: regex::Regex = regex::Regex::new(r"^([-+]?\d+)(((\.\d+([eE][-+]?\d+)?)|([eE][-+]?\d+))([fF]?))?$") @@ -399,7 +389,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse, S: BinarySource<'de>> } impl<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<'de>> Reader<'de, N> - for TextReader<'de, 'src, N::Embedded, Dec, S> + for TextReader<'de, 'src, N, Dec, S> { fn next(&mut self, read_annotations: bool) -> io::Result> { self.skip_whitespace(); @@ -488,7 +478,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<' fn open_record(&mut self, arity: Option) -> ReaderResult { self.skip_annotations()?; if self.peek()? != b'<' { - return Err(self.expected::(ExpectedKind::Record(arity))); + return Err(self.expected(ExpectedKind::Record(arity))); } self.skip()?; let mut b = B::Type::default(); @@ -508,13 +498,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<' _ => (), } Reader::::restore(self, &mark)?; - Err(self.expected::(ExpectedKind::SequenceOrSet)) + Err(self.expected(ExpectedKind::SequenceOrSet)) } fn open_sequence(&mut self) -> ReaderResult<()> { self.skip_annotations()?; if self.peek()? != b'[' { - return Err(self.expected::(ExpectedKind::Sequence)); + return Err(self.expected(ExpectedKind::Sequence)); } self.skip()?; Ok(()) @@ -531,13 +521,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<' _ => (), } Reader::::restore(self, &mark)?; - Err(self.expected::(ExpectedKind::Set)) + Err(self.expected(ExpectedKind::Set)) } fn open_dictionary(&mut self) -> ReaderResult<()> { self.skip_annotations()?; if self.peek()? != b'{' { - return Err(self.expected::(ExpectedKind::Dictionary)); + return Err(self.expected(ExpectedKind::Dictionary)); } self.skip()?; Ok(()) @@ -586,7 +576,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse, S: BinarySource<' _ => (), } Reader::::restore(self, &mark)?; - Err(self.expected::(ExpectedKind::Embedded)) + Err(self.expected(ExpectedKind::Embedded)) } fn close_embedded(&mut self) -> ReaderResult<()> { diff --git a/implementations/rust/preserves/tests/samples_tests.rs b/implementations/rust/preserves/tests/samples_tests.rs index 82f6257..9ffde78 100644 --- a/implementations/rust/preserves/tests/samples_tests.rs +++ b/implementations/rust/preserves/tests/samples_tests.rs @@ -20,6 +20,13 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result> { .collect() } +fn parse_all(text: &str) -> io::Result> { + BytesBinarySource::new(text.as_bytes()) + .text_iovalues() + .configured(true) + .collect() +} + #[test] fn compare_text_with_packed() -> io::Result<()> { use io::prelude::*; @@ -27,11 +34,9 @@ fn compare_text_with_packed() -> io::Result<()> { let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap(); let mut contents = String::new(); fh.read_to_string(&mut contents)?; - preserves::value::TextReader::new( - &mut BytesBinarySource::new(contents.as_bytes()), - preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec), - ) - .next_iovalue(true)? + BytesBinarySource::new(contents.as_bytes()) + .text_iovalues() + .demand_next(true)? }; let from_packed = { let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap(); @@ -149,9 +154,37 @@ fn run() -> io::Result<()> { ); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); } - TestCase::ParseError(_) => (), - TestCase::ParseShort(_) => (), - TestCase::ParseEOF(_) => (), + TestCase::ParseError(text) => { + match parse_all(text) { + Ok(_) => panic!("Unexpected success"), + Err(e) => { + if is_syntax_io_error(&e) { + // all is OK + } else { + panic!("Unexpected error {:?}", e) + } + } + } + } + TestCase::ParseShort(text) => { + assert!(if let Err(e) = BytesBinarySource::new(text.as_bytes()) + .text_iovalues() + .configured(true) + .next() + .unwrap() + { + is_eof_io_error(&e) + } else { + false + }) + } + TestCase::ParseEOF(text) => { + assert!(BytesBinarySource::new(text.as_bytes()) + .text_iovalues() + .configured(true) + .next() + .is_none()); + } TestCase::DecodeError(ref bin) => { match decode_all(&bin[..]) { Ok(_) => panic!("Unexpected success"),