A new approach to embedded-parameterised Reader

This commit is contained in:
Tony Garnock-Jones 2021-07-04 17:16:13 +02:00
parent 64ff818cd1
commit 41fe3c3440
14 changed files with 168 additions and 105 deletions

View File

@ -11,8 +11,9 @@ use crate::syntax::block::Formatter;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
use glob::glob; use glob::glob;
use preserves::value::BinarySource;
use preserves::value::IOBinarySource;
use preserves::value::Map; use preserves::value::Map;
use preserves::value::PackedReader;
use preserves::value::Reader; use preserves::value::Reader;
use preserves::value::Set; use preserves::value::Set;
@ -54,7 +55,8 @@ impl CompilerConfig {
pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>) -> Result<(), Error> { pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>) -> Result<(), Error> {
for i in inputs { for i in inputs {
let mut f = File::open(&i)?; let mut f = File::open(&i)?;
let mut reader = PackedReader::decode_read(&mut f); let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues();
let blob = reader.demand_next(false)?; let blob = reader.demand_next(false)?;
if let Ok(s) = Schema::try_from(&blob) { if let Ok(s) = Schema::try_from(&blob) {

View File

@ -31,13 +31,14 @@ mod tests {
#[test] #[test]
fn metaschema_parsing() -> Result<(), std::io::Error> { fn metaschema_parsing() -> Result<(), std::io::Error> {
use preserves::value::{Reader, IOValue}; use preserves::value::{BinarySource, IOBinarySource, IOValue, Reader};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::convert::From; use std::convert::From;
use crate::gen::schema::*; use crate::gen::schema::*;
let mut f = std::fs::File::open("../../../schema/schema.bin")?; let mut f = std::fs::File::open("../../../schema/schema.bin")?;
let mut reader = preserves::value::PackedReader::decode_read(&mut f); let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues();
let schema = reader.demand_next(false)?; let schema = reader.demand_next(false)?;
let parsed = Schema::try_from(&schema).expect("successful parse"); let parsed = Schema::try_from(&schema).expect("successful parse");
assert_eq!(schema, IOValue::from(&parsed)); assert_eq!(schema, IOValue::from(&parsed));

View File

@ -6,6 +6,7 @@ use preserves::value::Embeddable;
use preserves::value::IOResult; use preserves::value::IOResult;
use preserves::value::IOValue; use preserves::value::IOValue;
use preserves::value::NestedValue; use preserves::value::NestedValue;
use preserves::value::NoEmbeddedDomainDecode;
use preserves::value::Value; use preserves::value::Value;
use std::convert::From; use std::convert::From;
@ -13,9 +14,7 @@ use std::convert::TryFrom;
use std::sync::Arc; use std::sync::Arc;
pub fn decode_lit<D: Embeddable, N: NestedValue<D>>(bs: &[u8]) -> IOResult<N> { pub fn decode_lit<D: Embeddable, N: NestedValue<D>>(bs: &[u8]) -> IOResult<N> {
preserves::value::packed::from_bytes(bs).unwrap().copy_via( preserves::value::packed::from_bytes(bs, NoEmbeddedDomainDecode)
&mut |_| Err(std::io::Error::new(std::io::ErrorKind::Unsupported,
"Embedded values not supported in schema literals")))
} }
pub fn decode_embedded<D: Domain>( pub fn decode_embedded<D: Domain>(

View File

@ -15,7 +15,6 @@ gitlab = { repository = "preserves/preserves" }
num = "0.2" num = "0.2"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11" serde_bytes = "0.11"
lazy_static = "1.4.0"
[dev-dependencies] [dev-dependencies]
criterion = "0.3" criterion = "0.3"

View File

@ -1,4 +1,4 @@
use preserves::{de, value::{self, Reader, PackedReader}}; use preserves::{de, value::{self, Reader, IOBinarySource, BinarySource}};
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use std::fs::File; use std::fs::File;
use std::io::Error; use std::io::Error;
@ -33,7 +33,7 @@ enum Variety {
} }
fn try_file(kind: &str, path: &str) -> Result<(), Error> { fn try_file(kind: &str, path: &str) -> Result<(), Error> {
let fruits_value = PackedReader::decode_read(&mut File::open(path)?).demand_next(true)?; let fruits_value = IOBinarySource::new(&mut File::open(path)?).packed_iovalues().demand_next(true)?;
println!("{:?}", fruits_value); println!("{:?}", fruits_value);
let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?; let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?;

View File

@ -1,15 +1,17 @@
use serde::Deserialize; use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed}; use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::borrow::Cow; use std::borrow::Cow;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::value::PackedReader;
use super::value::{IOValue, IOValueDomainDecode, PackedReader};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource}; use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
pub use super::error::Error; pub use super::error::Error;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
pub struct Deserializer<'de, 'r, R: Reader<'de>> { pub struct Deserializer<'de, 'r, R: Reader<'de, IOValue, IOValue>> {
pub read: &'r mut R, pub read: &'r mut R,
phantom: PhantomData<&'de ()>, phantom: PhantomData<&'de ()>,
} }
@ -19,7 +21,7 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
where where
T: Deserialize<'de> T: Deserialize<'de>
{ {
from_reader(&mut PackedReader::new(BytesBinarySource::new(bytes))) from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainDecode))
} }
pub fn from_read<'de, 'r, IOR: std::io::Read, T>(read: &'r mut IOR) -> pub fn from_read<'de, 'r, IOR: std::io::Read, T>(read: &'r mut IOR) ->
@ -27,10 +29,10 @@ pub fn from_read<'de, 'r, IOR: std::io::Read, T>(read: &'r mut IOR) ->
where where
T: Deserialize<'de> T: Deserialize<'de>
{ {
from_reader(&mut PackedReader::new(IOBinarySource::new(read))) from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainDecode))
} }
pub fn from_reader<'r, 'de, R: Reader<'de>, T>(read: &'r mut R) -> pub fn from_reader<'r, 'de, R: Reader<'de, IOValue, IOValue>, T>(read: &'r mut R) ->
Result<T> Result<T>
where where
T: Deserialize<'de> T: Deserialize<'de>
@ -40,13 +42,13 @@ where
Ok(t) Ok(t)
} }
impl<'r, 'de, R: Reader<'de>> Deserializer<'de, 'r, R> { impl<'r, 'de, R: Reader<'de, IOValue, IOValue>> Deserializer<'de, 'r, R> {
pub fn from_reader(read: &'r mut R) -> Self { pub fn from_reader(read: &'r mut R) -> Self {
Deserializer { read, phantom: PhantomData } Deserializer { read, phantom: PhantomData }
} }
} }
impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deserializer<'de, 'r, R> impl<'r, 'de, 'a, R: Reader<'de, IOValue, IOValue>> serde::de::Deserializer<'de> for &'a mut Deserializer<'de, 'r, R>
{ {
type Error = Error; type Error = Error;
@ -258,11 +260,11 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
} }
} }
pub struct Seq<'de, 'r, 'a, R: Reader<'de>> { pub struct Seq<'de, 'r, 'a, R: Reader<'de, IOValue, IOValue>> {
de: &'a mut Deserializer<'de, 'r, R>, de: &'a mut Deserializer<'de, 'r, R>,
} }
impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue, IOValue>> Seq<'de, 'r, 'a, R> {
fn new(de: &'a mut Deserializer<'de, 'r, R>) -> Self { fn new(de: &'a mut Deserializer<'de, 'r, R>) -> Self {
Seq { de } Seq { de }
} }
@ -281,7 +283,7 @@ impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> {
} }
} }
impl<'de, 'r, 'a, R: Reader<'de>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error; type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> fn next_element_seed<T>(&mut self, seed: T) ->
@ -291,7 +293,7 @@ impl<'de, 'r, 'a, R: Reader<'de>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
} }
} }
impl<'de, 'r, 'a, R: Reader<'de>> MapAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error; type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> fn next_key_seed<K>(&mut self, seed: K) ->
@ -310,7 +312,7 @@ impl<'de, 'r, 'a, R: Reader<'de>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
} }
} }
impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue, IOValue>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> {
type Error = Error; type Error = Error;
type Variant = Seq<'de, 'r, 'a, R>; type Variant = Seq<'de, 'r, 'a, R>;
@ -323,7 +325,7 @@ impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de,
} }
} }
impl<'de, 'r, 'a, R: Reader<'de>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue, IOValue>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error; type Error = Error;
fn unit_variant(mut self) -> Result<()> { fn unit_variant(mut self) -> Result<()> {

View File

@ -1,6 +1,3 @@
#[macro_use]
extern crate lazy_static;
pub mod de; pub mod de;
pub mod ser; pub mod ser;
pub mod error; pub mod error;
@ -225,7 +222,7 @@ mod value_tests {
#[cfg(test)] #[cfg(test)]
mod decoder_tests { mod decoder_tests {
use crate::value::{Value, NestedValue, PackedReader, ConfiguredReader}; use crate::value::{Value, NestedValue, BinarySource, BytesBinarySource, ConfiguredReader};
use crate::de::from_bytes; use crate::de::from_bytes;
use crate::error::{Error, ExpectedKind, is_eof_io_error}; use crate::error::{Error, ExpectedKind, is_eof_io_error};
@ -247,7 +244,8 @@ mod decoder_tests {
#[test] fn skip_annotations_noskip() { #[test] fn skip_annotations_noskip() {
let buf = &b"\x85\x92\x91"[..]; let buf = &b"\x85\x92\x91"[..];
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&buf)); let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
let v = d.demand_next().unwrap(); let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 1); assert_eq!(v.annotations().slice().len(), 1);
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap()); assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
@ -256,7 +254,8 @@ mod decoder_tests {
#[test] fn skip_annotations_skip() { #[test] fn skip_annotations_skip() {
let buf = &b"\x85\x92\x91"[..]; let buf = &b"\x85\x92\x91"[..];
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&buf)); let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
d.set_read_annotations(false); d.set_read_annotations(false);
let v = d.demand_next().unwrap(); let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 0); assert_eq!(v.annotations().slice().len(), 0);
@ -266,7 +265,8 @@ mod decoder_tests {
#[test] fn multiple_values_buf_advanced() { #[test] fn multiple_values_buf_advanced() {
let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..]; let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 16); assert_eq!(buf.len(), 16);
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&buf)); let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
assert_eq!(d.reader.source.index, 0); assert_eq!(d.reader.source.index, 0);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping")); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
assert_eq!(d.reader.source.index, 8); assert_eq!(d.reader.source.index, 8);

View File

@ -0,0 +1,24 @@
use super::Embeddable;
use super::IOResult;
use super::IOValue;
pub trait DomainDecode<D: Embeddable> {
fn decode_embedded_iovalue(&mut self, v: IOValue) -> IOResult<D>;
}
pub struct IOValueDomainDecode;
impl DomainDecode<IOValue> for IOValueDomainDecode {
fn decode_embedded_iovalue(&mut self, v: IOValue) -> IOResult<IOValue> {
Ok(v)
}
}
pub struct NoEmbeddedDomainDecode;
impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainDecode {
fn decode_embedded_iovalue(&mut self, _v: IOValue) -> IOResult<D> {
Err(std::io::Error::new(std::io::ErrorKind::Unsupported,
"Embedded values not supported here"))
}
}

View File

@ -1,4 +1,5 @@
pub mod de; pub mod de;
pub mod domain;
pub mod magic; pub mod magic;
pub mod packed; pub mod packed;
pub mod reader; pub mod reader;
@ -9,9 +10,15 @@ pub mod writer;
pub use de::Deserializer; pub use de::Deserializer;
pub use de::from_value; pub use de::from_value;
pub use domain::DomainDecode;
pub use domain::IOValueDomainDecode;
pub use domain::NoEmbeddedDomainDecode;
pub use packed::PackedReader; pub use packed::PackedReader;
pub use packed::PackedWriter; pub use packed::PackedWriter;
pub use reader::BinarySource;
pub use reader::BytesBinarySource;
pub use reader::ConfiguredReader; pub use reader::ConfiguredReader;
pub use reader::IOBinarySource;
pub use reader::Reader; pub use reader::Reader;
pub use repr::AnnotatedValue; pub use repr::AnnotatedValue;
pub use repr::ArcValue; pub use repr::ArcValue;
@ -32,10 +39,6 @@ pub use ser::Serializer;
pub use ser::to_value; pub use ser::to_value;
pub use writer::Writer; pub use writer::Writer;
pub use repr::FALSE;
pub use repr::TRUE;
pub use repr::EMPTY_SEQ;
pub type IOResult<T> = std::result::Result<T, std::io::Error>; pub type IOResult<T> = std::result::Result<T, std::io::Error>;
pub fn invert_map<A, B>(m: &Map<A, B>) -> Map<B, A> pub fn invert_map<A, B>(m: &Map<A, B>) -> Map<B, A>

View File

@ -5,12 +5,26 @@ pub mod writer;
pub use reader::PackedReader; pub use reader::PackedReader;
pub use writer::PackedWriter; pub use writer::PackedWriter;
use super::{Reader, IOValue, IOResult}; use super::{BinarySource, DomainDecode, Embeddable, IOResult, IOValue, IOValueDomainDecode, NestedValue, Reader};
pub fn from_bytes(bs: &[u8]) -> IOResult<IOValue> { pub fn from_bytes<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>>(
PackedReader::decode_bytes(bs).demand_next(false) bs: &[u8],
decode_embedded: Dec,
) -> IOResult<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(false)
} }
pub fn annotated_from_bytes(bs: &[u8]) -> IOResult<IOValue> { pub fn iovalue_from_bytes(bs: &[u8]) -> IOResult<IOValue> {
PackedReader::decode_bytes(bs).demand_next(true) from_bytes(bs, IOValueDomainDecode)
}
pub fn annotated_from_bytes<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>>(
bs: &[u8],
decode_embedded: Dec,
) -> IOResult<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(true)
}
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> IOResult<IOValue> {
annotated_from_bytes(bs, IOValueDomainDecode)
} }

View File

@ -1,5 +1,8 @@
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error};
use num::bigint::BigInt; use num::bigint::BigInt;
use num::traits::cast::{FromPrimitive, ToPrimitive}; use num::traits::cast::{FromPrimitive, ToPrimitive};
use std::borrow::Cow; use std::borrow::Cow;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::convert::TryInto; use std::convert::TryInto;
@ -7,21 +10,19 @@ use std::marker::PhantomData;
use super::constants::Tag; use super::constants::Tag;
use super::super::{ use super::super::{
FALSE, DomainDecode,
Embeddable,
IOResult, IOResult,
IOValue, IOValueDomainDecode,
Map, Map,
NestedValue, NestedValue,
Record, Record,
Set, Set,
TRUE,
Value, Value,
reader::{ reader::{
BinarySource, BinarySource,
BytesBinarySource,
ConfiguredReader, ConfiguredReader,
IOBinarySource,
Reader, Reader,
ReaderResult, ReaderResult,
}, },
@ -29,14 +30,16 @@ use super::super::{
signed_integer::SignedInteger, signed_integer::SignedInteger,
}; };
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error}; pub struct PackedReader<'de, 'src, D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>, S: BinarySource<'de>> {
pub source: &'src mut S,
pub struct PackedReader<'de, S: BinarySource<'de>> { pub decode_embedded: Dec,
pub source: S, phantom: PhantomData<&'de (D, N)>,
phantom: PhantomData<&'de ()>,
} }
impl<'de, S: BinarySource<'de>> BinarySource<'de> for PackedReader<'de, S> { impl<'de, 'src, D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>, S: BinarySource<'de>>
BinarySource<'de>
for PackedReader<'de, 'src, D, N, Dec, S>
{
fn skip(&mut self) -> IOResult<()> { fn skip(&mut self) -> IOResult<()> {
self.source.skip() self.source.skip()
} }
@ -55,21 +58,9 @@ fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
error::Error::NumberOutOfRange(i.into()) error::Error::NumberOutOfRange(i.into())
} }
impl<'de> PackedReader<'de, BytesBinarySource<'de>> { impl<'de, 'src, D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>, S: BinarySource<'de>> PackedReader<'de, 'src, D, N, Dec, S> {
pub fn decode_bytes(bytes: &'de [u8]) -> Self { pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self {
PackedReader::new(BytesBinarySource::new(bytes)) PackedReader { source, decode_embedded, phantom: PhantomData }
}
}
impl<'de, 'a, IOR: std::io::Read> PackedReader<'de, IOBinarySource<'a, IOR>> {
pub fn decode_read(read: &'a mut IOR) -> Self {
PackedReader::new(IOBinarySource::new(read))
}
}
impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
pub fn new(source: S) -> Self {
PackedReader { source, phantom: PhantomData }
} }
fn read(&mut self) -> IOResult<u8> { fn read(&mut self) -> IOResult<u8> {
@ -234,16 +225,19 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
} }
} }
impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { impl<'de, 'src, D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>, S: BinarySource<'de>>
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> { Reader<'de, D, N>
for PackedReader<'de, 'src, D, N, Dec, S>
{
fn next(&mut self, read_annotations: bool) -> IOResult<Option<N>> {
match self.peek() { match self.peek() {
Err(e) if is_eof_io_error(&e) => return Ok(None), Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e), Err(e) => return Err(e),
Ok(_) => (), Ok(_) => (),
} }
Ok(Some(match Tag::try_from(self.read()?)? { Ok(Some(match Tag::try_from(self.read()?)? {
Tag::False => FALSE.clone(), Tag::False => N::new(false),
Tag::True => TRUE.clone(), Tag::True => N::new(true),
Tag::Float => { Tag::Float => {
let mut bs = [0; 4]; let mut bs = [0; 4];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
@ -263,7 +257,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces(); let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice()); annotations.extend_from_slice(existing_annotations.slice());
IOValue::wrap(Annotations::new(Some(annotations)), v) N::wrap(Annotations::new(Some(annotations)), v)
} else { } else {
self.skip_value()?; self.skip_value()?;
while Tag::try_from(self.peek()?)? == Tag::Annotation { while Tag::try_from(self.peek()?)? == Tag::Annotation {
@ -274,8 +268,8 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
} }
Tag::Embedded => { Tag::Embedded => {
let v = self.demand_next(read_annotations)?; let v = PackedReader::new(self.source, IOValueDomainDecode).demand_next(read_annotations)?;
Value::Embedded(v).wrap() Value::Embedded(self.decode_embedded.decode_embedded_iovalue(v)?).wrap()
} }
Tag::SmallInteger(v) => { Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs // TODO: prebuild these in value.rs
@ -304,7 +298,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
Tag::Record => { Tag::Record => {
let iter = DelimitedStream { reader: self.configured(read_annotations) }; let iter = DelimitedStream { reader: self.configured(read_annotations) };
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?; let vs = iter.collect::<IOResult<Vec<N>>>()?;
if vs.is_empty() { if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record")) return Err(io_syntax_error("Too few elements in encoded record"))
} }
@ -312,7 +306,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
Tag::Sequence => { Tag::Sequence => {
let iter = DelimitedStream { reader: self.configured(read_annotations) }; let iter = DelimitedStream { reader: self.configured(read_annotations) };
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?; let vs = iter.collect::<IOResult<Vec<N>>>()?;
Value::Sequence(vs).wrap() Value::Sequence(vs).wrap()
} }
Tag::Set => { Tag::Set => {
@ -450,13 +444,21 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
} }
struct DelimitedStream<'a, 'de, S: BinarySource<'de>> { struct DelimitedStream
reader: ConfiguredReader<'de, &'a mut PackedReader<'de, S>>, <'a, 'de, 'src,
D: Embeddable,
N: NestedValue<D>,
Dec: DomainDecode<D>,
S: BinarySource<'de>>
{
reader: ConfiguredReader<'de, D, N, &'a mut PackedReader<'de, 'src, D, N, Dec, S>>,
} }
impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S> impl<'a, 'de, 'src, D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>, S: BinarySource<'de>>
Iterator
for DelimitedStream<'a, 'de, 'src, D, N, Dec, S>
{ {
type Item = IOResult<IOValue>; type Item = IOResult<N>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match self.reader.reader.peekend() { match self.reader.reader.peekend() {
Err(e) => Some(Err(e)), Err(e) => Some(Err(e)),

View File

@ -1,14 +1,15 @@
use crate::error::{self, ExpectedKind, Received, io_eof};
use std::borrow::Cow; use std::borrow::Cow;
use std::io::Read; use std::io::Read;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::repr::{NestedValue, IOValue};
use super::IOResult; use super::{DomainDecode, Embeddable, IOResult, IOValue, IOValueDomainDecode, NestedValue};
use crate::error::{self, ExpectedKind, Received, io_eof};
pub type ReaderResult<T> = std::result::Result<T, error::Error>; pub type ReaderResult<T> = std::result::Result<T, error::Error>;
pub trait Reader<'de> { pub trait Reader<'de, D: Embeddable, N: NestedValue<D>> {
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>; fn next(&mut self, read_annotations: bool) -> IOResult<Option<N>>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()>; fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()>;
fn open_sequence_or_set(&mut self) -> ReaderResult<()>; fn open_sequence_or_set(&mut self) -> ReaderResult<()>;
fn open_sequence(&mut self) -> ReaderResult<()>; fn open_sequence(&mut self) -> ReaderResult<()>;
@ -26,7 +27,7 @@ pub trait Reader<'de> {
Ok(()) Ok(())
} }
fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> { fn demand_next(&mut self, read_annotations: bool) -> IOResult<N> {
self.next(read_annotations)?.ok_or_else(io_eof) self.next(read_annotations)?.ok_or_else(io_eof)
} }
@ -81,7 +82,7 @@ pub trait Reader<'de> {
} }
} }
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, Self> fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, D, N, Self>
where where
Self: std::marker::Sized Self: std::marker::Sized
{ {
@ -116,8 +117,11 @@ pub trait Reader<'de> {
} }
} }
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { impl<'r, 'de, D: Embeddable, N: NestedValue<D>, R: Reader<'de, D, N>>
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> { Reader<'de, D, N>
for &'r mut R
{
fn next(&mut self, read_annotations: bool) -> IOResult<Option<N>> {
(*self).next(read_annotations) (*self).next(read_annotations)
} }
@ -155,11 +159,24 @@ impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
} }
pub trait BinarySource<'de> { pub trait BinarySource<'de>: Sized {
fn skip(&mut self) -> IOResult<()>; fn skip(&mut self) -> IOResult<()>;
fn peek(&mut self) -> IOResult<u8>; fn peek(&mut self) -> IOResult<u8>;
fn readbytes(&mut self, count: usize) -> IOResult<Cow<'de, [u8]>>; fn readbytes(&mut self, count: usize) -> IOResult<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()>; fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()>;
fn packed<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>>(
&mut self,
decode_embedded: Dec,
) -> super::PackedReader<'de, '_, D, N, Dec, Self> {
super::PackedReader::new(self, decode_embedded)
}
fn packed_iovalues(&mut self) ->
super::PackedReader<'de, '_, IOValue, IOValue, IOValueDomainDecode, Self>
{
self.packed(IOValueDomainDecode)
}
} }
pub struct IOBinarySource<'a, R: Read> { pub struct IOBinarySource<'a, R: Read> {
@ -258,13 +275,13 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
} }
} }
pub struct ConfiguredReader<'de, R: Reader<'de>> { pub struct ConfiguredReader<'de, D: Embeddable, N: NestedValue<D>, R: Reader<'de, D, N>> {
pub reader: R, pub reader: R,
pub read_annotations: bool, pub read_annotations: bool,
phantom: PhantomData<&'de ()>, phantom: PhantomData<&'de (D, N)>,
} }
impl<'de, R: Reader<'de>> ConfiguredReader<'de, R> { impl<'de, D: Embeddable, N: NestedValue<D>, R: Reader<'de, D, N>> ConfiguredReader<'de, D, N, R> {
pub fn new(reader: R) -> Self { pub fn new(reader: R) -> Self {
reader.configured(true) reader.configured(true)
} }
@ -273,13 +290,16 @@ impl<'de, R: Reader<'de>> ConfiguredReader<'de, R> {
self.read_annotations = read_annotations self.read_annotations = read_annotations
} }
pub fn demand_next(&mut self) -> IOResult<IOValue> { pub fn demand_next(&mut self) -> IOResult<N> {
self.reader.demand_next(self.read_annotations) self.reader.demand_next(self.read_annotations)
} }
} }
impl<'de, R: Reader<'de>> std::iter::Iterator for ConfiguredReader<'de, R> { impl<'de, D: Embeddable, N: NestedValue<D>, R: Reader<'de, D, N>>
type Item = IOResult<IOValue>; std::iter::Iterator
for ConfiguredReader<'de, D, N, R>
{
type Item = IOResult<N>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match self.reader.next(self.read_annotations) { match self.reader.next(self.read_annotations) {
Err(e) => Some(Err(e)), Err(e) => Some(Err(e)),

View File

@ -1046,12 +1046,6 @@ impl<D: Embeddable> Debug for ArcValue<D> {
pub struct IOValue(Arc<AnnotatedValue<IOValue, IOValue>>); pub struct IOValue(Arc<AnnotatedValue<IOValue, IOValue>>);
pub type UnwrappedIOValue = Value<IOValue, IOValue>; pub type UnwrappedIOValue = Value<IOValue, IOValue>;
lazy_static! {
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(false))));
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(true))));
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Sequence(Vec::new()))));
}
impl Domain for IOValue {} impl Domain for IOValue {}
impl NestedValue<IOValue> for IOValue { impl NestedValue<IOValue> for IOValue {

View File

@ -1,7 +1,9 @@
use preserves::error::{is_eof_io_error, is_syntax_io_error}; use preserves::error::{is_eof_io_error, is_syntax_io_error};
use preserves::symbol::Symbol; use preserves::symbol::Symbol;
use preserves::value::BinarySource;
use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource;
use preserves::value::IOValue; use preserves::value::IOValue;
use preserves::value::PackedReader;
use preserves::value::PackedWriter; use preserves::value::PackedWriter;
use preserves::value::Reader; use preserves::value::Reader;
use preserves::value::de::from_value as deserialize_from_value; use preserves::value::de::from_value as deserialize_from_value;
@ -11,12 +13,13 @@ mod samples;
use samples::*; use samples::*;
fn decode_all(bytes: &'_ [u8]) -> Result<Vec<IOValue>, std::io::Error> { fn decode_all(bytes: &'_ [u8]) -> Result<Vec<IOValue>, std::io::Error> {
PackedReader::decode_bytes(bytes).configured(true).collect() BytesBinarySource::new(bytes).packed_iovalues().configured(true).collect()
} }
#[test] fn run() -> std::io::Result<()> { #[test] fn run() -> std::io::Result<()> {
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
let mut d = PackedReader::decode_read(&mut fh).configured(true); let mut src = IOBinarySource::new(&mut fh);
let mut d = src.packed_iovalues().configured(true);
let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap(); let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap();
// println!("{:#?}", tests); // println!("{:#?}", tests);
@ -55,14 +58,14 @@ fn decode_all(bytes: &'_ [u8]) -> Result<Vec<IOValue>, std::io::Error> {
} }
} }
TestCase::DecodeShort(ref bin) => { TestCase::DecodeShort(ref bin) => {
assert!(if let Err(e) = PackedReader::decode_bytes(bin).configured(true).next().unwrap() { assert!(if let Err(e) = BytesBinarySource::new(bin).packed_iovalues().configured(true).next().unwrap() {
is_eof_io_error(&e) is_eof_io_error(&e)
} else { } else {
false false
}) })
} }
TestCase::DecodeEOF(ref bin) => { TestCase::DecodeEOF(ref bin) => {
assert!(PackedReader::decode_bytes(bin).configured(true).next().is_none()); assert!(BytesBinarySource::new(bin).packed_iovalues().configured(true).next().is_none());
} }
} }
} }