A new approach to embedded-parameterised Reader
This commit is contained in:
parent
64ff818cd1
commit
41fe3c3440
|
@ -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) {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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<()> {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue