Enable parse tests in rust
This commit is contained in:
parent
c30073c3f9
commit
755a8bc73b
|
@ -373,7 +373,7 @@ pub trait BinarySource<'de>: Sized {
|
||||||
fn text<N: NestedValue, Dec: DomainParse<N::Embedded>>(
|
fn text<N: NestedValue, Dec: DomainParse<N::Embedded>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
decode_embedded: Dec,
|
decode_embedded: Dec,
|
||||||
) -> super::TextReader<'de, '_, N::Embedded, Dec, Self> {
|
) -> super::TextReader<'de, '_, N, Dec, Self> {
|
||||||
super::TextReader::new(self, decode_embedded)
|
super::TextReader::new(self, decode_embedded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@ use crate::value::reader::ReaderResult;
|
||||||
use crate::value::repr::Annotations;
|
use crate::value::repr::Annotations;
|
||||||
use crate::value::CompoundClass;
|
use crate::value::CompoundClass;
|
||||||
use crate::value::DomainParse;
|
use crate::value::DomainParse;
|
||||||
use crate::value::DummyValue;
|
|
||||||
use crate::value::Embeddable;
|
|
||||||
use crate::value::IOValue;
|
use crate::value::IOValue;
|
||||||
use crate::value::IOValueDomainCodec;
|
use crate::value::IOValueDomainCodec;
|
||||||
use crate::value::Map;
|
use crate::value::Map;
|
||||||
|
@ -34,16 +32,15 @@ use num::bigint::BigInt;
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::iter::FromIterator;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
/// The text syntax Preserves reader.
|
/// 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.
|
/// Underlying source of (utf8) bytes.
|
||||||
pub source: &'src mut S,
|
pub source: &'src mut S,
|
||||||
/// Decoder for producing Rust values embedded in the text.
|
/// Decoder for producing Rust values embedded in the text.
|
||||||
pub dec: Dec,
|
pub dec: Dec,
|
||||||
phantom: PhantomData<&'de D>,
|
phantom: PhantomData<&'de N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_utf8(bs: Vec<u8>) -> io::Result<String> {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
|
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'de>>
|
||||||
TextReader<'de, 'src, D, Dec, S>
|
TextReader<'de, 'src, N, Dec, S>
|
||||||
{
|
{
|
||||||
/// Construct a new reader from a byte (utf8) source and embedded-value decoder.
|
/// Construct a new reader from a byte (utf8) source and embedded-value decoder.
|
||||||
pub fn new(source: &'src mut S, dec: Dec) -> Self {
|
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.
|
// 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) {
|
match Reader::<N>::demand_next(self, true) {
|
||||||
Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
|
Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
|
||||||
Err(e) => e.into(),
|
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();
|
let mut vs = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
self.skip_whitespace();
|
self.skip_whitespace();
|
||||||
|
@ -133,7 +130,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
|
||||||
}
|
}
|
||||||
b'@' => {
|
b'@' => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
Reader::<DummyValue<D>>::skip_value(self)?;
|
self.skip_value()?;
|
||||||
}
|
}
|
||||||
_ => return Ok(()),
|
_ => 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'"' {
|
if self.next_byte()? != b'"' {
|
||||||
return Err(io_syntax_error(
|
return Err(io_syntax_error(
|
||||||
"Missing open-double-quote in hex-encoded floating-point number",
|
"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(
|
Ok(N::new(
|
||||||
&self.read_stringlike(
|
&self.read_stringlike(
|
||||||
Vec::new(),
|
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();
|
let mut bs = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
self.skip_whitespace();
|
self.skip_whitespace();
|
||||||
|
@ -304,11 +301,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upto<N: NestedValue<Embedded = D>>(
|
fn upto(&mut self, delimiter: u8, read_annotations: bool) -> io::Result<Vec<N>> {
|
||||||
&mut self,
|
|
||||||
delimiter: u8,
|
|
||||||
read_annotations: bool,
|
|
||||||
) -> io::Result<Vec<N>> {
|
|
||||||
let mut vs = Vec::new();
|
let mut vs = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
self.skip_whitespace();
|
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>>(
|
fn read_dictionary(&mut self, read_annotations: bool) -> io::Result<N> {
|
||||||
&mut self,
|
|
||||||
read_annotations: bool,
|
|
||||||
) -> io::Result<N> {
|
|
||||||
let mut d = Map::new();
|
let mut d = Map::new();
|
||||||
loop {
|
loop {
|
||||||
self.skip_whitespace();
|
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! {
|
lazy_static! {
|
||||||
static ref NUMBER_RE: regex::Regex =
|
static ref NUMBER_RE: regex::Regex =
|
||||||
regex::Regex::new(r"^([-+]?\d+)(((\.\d+([eE][-+]?\d+)?)|([eE][-+]?\d+))([fF]?))?$")
|
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>
|
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>> {
|
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
|
||||||
self.skip_whitespace();
|
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> {
|
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
|
||||||
self.skip_annotations()?;
|
self.skip_annotations()?;
|
||||||
if self.peek()? != b'<' {
|
if self.peek()? != b'<' {
|
||||||
return Err(self.expected::<N>(ExpectedKind::Record(arity)));
|
return Err(self.expected(ExpectedKind::Record(arity)));
|
||||||
}
|
}
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let mut b = B::Type::default();
|
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)?;
|
Reader::<N>::restore(self, &mark)?;
|
||||||
Err(self.expected::<N>(ExpectedKind::SequenceOrSet))
|
Err(self.expected(ExpectedKind::SequenceOrSet))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_sequence(&mut self) -> ReaderResult<()> {
|
fn open_sequence(&mut self) -> ReaderResult<()> {
|
||||||
self.skip_annotations()?;
|
self.skip_annotations()?;
|
||||||
if self.peek()? != b'[' {
|
if self.peek()? != b'[' {
|
||||||
return Err(self.expected::<N>(ExpectedKind::Sequence));
|
return Err(self.expected(ExpectedKind::Sequence));
|
||||||
}
|
}
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -531,13 +521,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Reader::<N>::restore(self, &mark)?;
|
Reader::<N>::restore(self, &mark)?;
|
||||||
Err(self.expected::<N>(ExpectedKind::Set))
|
Err(self.expected(ExpectedKind::Set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_dictionary(&mut self) -> ReaderResult<()> {
|
fn open_dictionary(&mut self) -> ReaderResult<()> {
|
||||||
self.skip_annotations()?;
|
self.skip_annotations()?;
|
||||||
if self.peek()? != b'{' {
|
if self.peek()? != b'{' {
|
||||||
return Err(self.expected::<N>(ExpectedKind::Dictionary));
|
return Err(self.expected(ExpectedKind::Dictionary));
|
||||||
}
|
}
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -586,7 +576,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Reader::<N>::restore(self, &mark)?;
|
Reader::<N>::restore(self, &mark)?;
|
||||||
Err(self.expected::<N>(ExpectedKind::Embedded))
|
Err(self.expected(ExpectedKind::Embedded))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_embedded(&mut self) -> ReaderResult<()> {
|
fn close_embedded(&mut self) -> ReaderResult<()> {
|
||||||
|
|
|
@ -20,6 +20,13 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_all(text: &str) -> io::Result<Vec<IOValue>> {
|
||||||
|
BytesBinarySource::new(text.as_bytes())
|
||||||
|
.text_iovalues()
|
||||||
|
.configured(true)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare_text_with_packed() -> io::Result<()> {
|
fn compare_text_with_packed() -> io::Result<()> {
|
||||||
use io::prelude::*;
|
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 fh = std::fs::File::open("../../../tests/samples.pr").unwrap();
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
fh.read_to_string(&mut contents)?;
|
fh.read_to_string(&mut contents)?;
|
||||||
preserves::value::TextReader::new(
|
BytesBinarySource::new(contents.as_bytes())
|
||||||
&mut BytesBinarySource::new(contents.as_bytes()),
|
.text_iovalues()
|
||||||
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec),
|
.demand_next(true)?
|
||||||
)
|
|
||||||
.next_iovalue(true)?
|
|
||||||
};
|
};
|
||||||
let from_packed = {
|
let from_packed = {
|
||||||
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
|
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()]);
|
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
||||||
}
|
}
|
||||||
TestCase::ParseError(_) => (),
|
TestCase::ParseError(text) => {
|
||||||
TestCase::ParseShort(_) => (),
|
match parse_all(text) {
|
||||||
TestCase::ParseEOF(_) => (),
|
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) => {
|
TestCase::DecodeError(ref bin) => {
|
||||||
match decode_all(&bin[..]) {
|
match decode_all(&bin[..]) {
|
||||||
Ok(_) => panic!("Unexpected success"),
|
Ok(_) => panic!("Unexpected success"),
|
||||||
|
|
Loading…
Reference in New Issue