Enable parse tests in rust

This commit is contained in:
Tony Garnock-Jones 2023-10-29 21:00:56 +01:00
parent c30073c3f9
commit 755a8bc73b
3 changed files with 62 additions and 39 deletions

View File

@ -373,7 +373,7 @@ pub trait BinarySource<'de>: Sized {
fn text<N: NestedValue, Dec: DomainParse<N::Embedded>>(
&mut self,
decode_embedded: Dec,
) -> super::TextReader<'de, '_, N::Embedded, Dec, Self> {
) -> super::TextReader<'de, '_, N, Dec, Self> {
super::TextReader::new(self, decode_embedded)
}

View File

@ -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<D>, S: BinarySource<'de>> {
pub struct TextReader<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, 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<u8>) -> io::Result<String> {
@ -58,8 +55,8 @@ fn append_codepoint(bs: &mut Vec<u8>, n: u32) -> io::Result<()> {
Ok(())
}
impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
TextReader<'de, 'src, D, Dec, S>
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, 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<D>, S: BinarySource<'de>>
}
// TODO: This is a duplicate of fn expected in PackedReader.
fn expected<N: NestedValue<Embedded = D>>(&mut self, k: ExpectedKind) -> Error {
fn expected(&mut self, k: ExpectedKind) -> Error {
match Reader::<N>::demand_next(self, true) {
Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
Err(e) => e.into(),
}
}
fn gather_annotations<N: NestedValue<Embedded = D>>(&mut self) -> ReaderResult<Vec<N>> {
fn gather_annotations(&mut self) -> ReaderResult<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
@ -133,7 +130,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
b'@' => {
self.skip()?;
Reader::<DummyValue<D>>::skip_value(self)?;
self.skip_value()?;
}
_ => return Ok(()),
}
@ -159,7 +156,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn read_hex_float<N: NestedValue>(&mut self, bytecount: usize) -> io::Result<N> {
fn read_hex_float(&mut self, bytecount: usize) -> io::Result<N> {
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<D>, S: BinarySource<'de>>
)?)
}
fn read_literal_binary<N: NestedValue>(&mut self) -> io::Result<N> {
fn read_literal_binary(&mut self) -> io::Result<N> {
Ok(N::new(
&self.read_stringlike(
Vec::new(),
@ -281,7 +278,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn read_base64_binary<N: NestedValue>(&mut self) -> io::Result<N> {
fn read_base64_binary(&mut self) -> io::Result<N> {
let mut bs = Vec::new();
loop {
self.skip_whitespace();
@ -304,11 +301,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn upto<N: NestedValue<Embedded = D>>(
&mut self,
delimiter: u8,
read_annotations: bool,
) -> io::Result<Vec<N>> {
fn upto(&mut self, delimiter: u8, read_annotations: bool) -> io::Result<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
@ -320,10 +313,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn read_dictionary<N: NestedValue<Embedded = D>>(
&mut self,
read_annotations: bool,
) -> io::Result<N> {
fn read_dictionary(&mut self, read_annotations: bool) -> io::Result<N> {
let mut d = Map::new();
loop {
self.skip_whitespace();
@ -341,7 +331,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn read_raw_symbol_or_number<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
fn read_raw_symbol_or_number(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
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<D>, S: BinarySource<'de>>
}
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, 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<Option<N>> {
self.skip_whitespace();
@ -488,7 +478,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
self.skip_annotations()?;
if self.peek()? != b'<' {
return Err(self.expected::<N>(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<N::Embedded>, S: BinarySource<'
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::SequenceOrSet))
Err(self.expected(ExpectedKind::SequenceOrSet))
}
fn open_sequence(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'[' {
return Err(self.expected::<N>(ExpectedKind::Sequence));
return Err(self.expected(ExpectedKind::Sequence));
}
self.skip()?;
Ok(())
@ -531,13 +521,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::Set))
Err(self.expected(ExpectedKind::Set))
}
fn open_dictionary(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'{' {
return Err(self.expected::<N>(ExpectedKind::Dictionary));
return Err(self.expected(ExpectedKind::Dictionary));
}
self.skip()?;
Ok(())
@ -586,7 +576,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::Embedded))
Err(self.expected(ExpectedKind::Embedded))
}
fn close_embedded(&mut self) -> ReaderResult<()> {

View File

@ -20,6 +20,13 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
.collect()
}
fn parse_all(text: &str) -> io::Result<Vec<IOValue>> {
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"),