Blue Rust implementation (WIP)

This commit is contained in:
Tony Garnock-Jones 2022-07-10 13:25:35 +02:00
parent d22d0d7120
commit c2a48a9b78
28 changed files with 2036 additions and 2084 deletions

View File

@ -108,8 +108,9 @@ pub struct CompilerConfig {
pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> { pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> {
let mut f = File::open(&i)?; let mut f = File::open(&i)?;
let mut src = IOBinarySource::new(&mut f); let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues(); let mut reader = src.packed().iovalues();
let blob = reader.demand_next(false)?; reader.set_read_annotations(false);
let blob = reader.demand_next()?;
let language = Language::default(); let language = Language::default();
if let Ok(s) = language.parse(&blob) { if let Ok(s) = language.parse(&blob) {
@ -139,8 +140,8 @@ impl CompilerConfig {
) -> Self { ) -> Self {
CompilerConfig { CompilerConfig {
bundle: Map::new(), bundle: Map::new(),
output_dir: output_dir, output_dir,
fully_qualified_module_prefix: fully_qualified_module_prefix, fully_qualified_module_prefix,
support_crate: "preserves_schema".to_owned(), support_crate: "preserves_schema".to_owned(),
external_modules: Map::new(), external_modules: Map::new(),
plugins: vec![ plugins: vec![

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,9 @@ mod tests {
let mut f = std::fs::File::open("../../../schema/schema.bin")?; let mut f = std::fs::File::open("../../../schema/schema.bin")?;
let mut src = IOBinarySource::new(&mut f); let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues(); let mut reader = src.packed().iovalues();
let schema = reader.demand_next(false)?; reader.set_read_annotations(false);
let schema = reader.demand_next()?;
let language = crate::gen::Language::default(); let language = crate::gen::Language::default();
let parsed = Schema::parse(&language, &schema).expect("successful parse"); let parsed = Schema::parse(&language, &schema).expect("successful parse");
assert_eq!(schema, parsed.unparse(&language)); assert_eq!(schema, parsed.unparse(&language));

View File

@ -39,7 +39,7 @@ impl<'a, V: NestedValue> Context<'a, V> {
} }
pub fn dynamic_unparse(&mut self, _module: &Vec<String>, _name: &str, _w: &V) -> Option<V> { pub fn dynamic_unparse(&mut self, _module: &Vec<String>, _name: &str, _w: &V) -> Option<V> {
panic!("Not yet implemented"); todo!("Not yet implemented");
} }
} }

View File

@ -1,6 +1,9 @@
pub use lazy_static::lazy_static; pub use lazy_static::lazy_static;
pub use preserves; pub use preserves;
pub use preserves::value::ConfiguredReader;
pub use preserves::value::DomainDecode;
pub use preserves::value::Embeddable;
pub use preserves::value::Reader; pub use preserves::value::Reader;
pub use preserves::value::boundary as B; pub use preserves::value::boundary as B;
@ -59,15 +62,15 @@ impl<L, N: NestedValue> Codec<N> for L {
} }
} }
pub trait Deserialize<'de, N: NestedValue, R: Reader<'de, N>> pub trait Deserialize<'de, _Value: NestedValue, _Dec: DomainDecode<_Value::Embedded>, _R: Reader<'de>>
where where
Self: Sized Self: Sized
{ {
fn deserialize(r: &mut R) -> Result<Self, ParseError>; fn deserialize(c: &mut ConfiguredReader<'de, _Value, _Dec, _R>) -> Result<Self, ParseError>;
} }
pub fn decode_lit<N: NestedValue>(bs: &[u8]) -> io::Result<N> { pub fn decode_lit<N: NestedValue>(bs: &[u8]) -> io::Result<N> {
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec) preserves::value::packed::from_bytes(bs, &mut NoEmbeddedDomainCodec)
} }
pub fn decode_embedded<D: Domain>( pub fn decode_embedded<D: Domain>(
@ -100,7 +103,7 @@ pub enum ParseError {
impl From<preserves::error::Error> for ParseError { impl From<preserves::error::Error> for ParseError {
fn from(v: preserves::error::Error) -> Self { fn from(v: preserves::error::Error) -> Self {
match v { match v {
preserves::error::Error::Expected(_, _) => preserves::error::Error::Expected(_) =>
ParseError::ConformanceError("preserves::error::Error::Expected"), ParseError::ConformanceError("preserves::error::Error::Expected"),
_ => _ =>
ParseError::Preserves(v), ParseError::Preserves(v),

View File

@ -33,7 +33,7 @@ enum Variety {
} }
fn try_file(kind: &str, path: &str) -> io::Result<()> { fn try_file(kind: &str, path: &str) -> io::Result<()> {
let fruits_value = IOBinarySource::new(&mut File::open(path)?).packed_iovalues().demand_next(true)?; let fruits_value = IOBinarySource::new(&mut File::open(path)?).packed().iovalues().demand_next()?;
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

@ -6,14 +6,15 @@ use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::value::boundary as B; use super::value::boundary as B;
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec}; use super::value::{IOValueDomainCodec, PackedReader, TextReader};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource}; use super::value::reader::Reader;
use super::value::source::{IOBinarySource, BytesBinarySource};
pub use super::error::Error; pub use super::error::{Error, ExpectedKind};
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, IOValue>> { pub struct Deserializer<'de, 'r, R: Reader<'de>> {
pub read: &'r mut R, pub read: &'r mut R,
phantom: PhantomData<&'de ()>, phantom: PhantomData<&'de ()>,
} }
@ -23,12 +24,11 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
where where
T: Deserialize<'de> T: Deserialize<'de>
{ {
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainCodec)) from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes)))
} }
pub fn from_text<'de, T>(text: &'de str) -> Result<T> where T: Deserialize<'de> { pub fn from_text<'de, T>(text: &'de str) -> Result<T> where T: Deserialize<'de> {
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes()), from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes())))
ViaCodec::new(IOValueDomainCodec)))
} }
pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) -> pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
@ -36,10 +36,10 @@ pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
where where
T: Deserialize<'de> T: Deserialize<'de>
{ {
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainCodec)) from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read)))
} }
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue>, T>(read: &'r mut R) -> pub fn from_reader<'r, 'de, R: Reader<'de>, T>(read: &'r mut R) ->
Result<T> Result<T>
where where
T: Deserialize<'de> T: Deserialize<'de>
@ -49,13 +49,29 @@ where
Ok(t) Ok(t)
} }
impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> { impl<'r, 'de, R: Reader<'de>> 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 }
} }
fn new_record_boundary(&mut self) -> Result<B::Type> {
let b = B::start(B::Item::RecordLabel);
self.read.boundary(&b)?;
Ok(b)
}
fn open_simple_record(&mut self, label: &str) -> Result<B::Type> {
self.read.open_simple_record(label)?;
self.new_record_boundary()
}
fn open_record(&mut self) -> Result<B::Type> {
self.read.open_record()?;
self.new_record_boundary()
}
} }
impl<'r, 'de, 'a, R: Reader<'de, IOValue>> impl<'r, 'de, 'a, R: Reader<'de>>
serde::de::Deserializer<'de> serde::de::Deserializer<'de>
for &'a mut Deserializer<'de, 'r, R> for &'a mut Deserializer<'de, 'r, R>
{ {
@ -155,19 +171,26 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
if let Some(mut b) = self.read.open_option()? { let mut b = self.open_record()?;
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?; match self.read.next_symbol()?.as_ref() {
let result = visitor.visit_some(&mut *self)?; "None" => {
self.read.ensure_complete(b, &B::Item::RecordField)?; self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result) visitor.visit_none::<Error>()
} else { }
Ok(visitor.visit_none::<Error>()?) "Some" => {
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_some(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
}
_ =>
Err(Error::Expected(ExpectedKind::Option)),
} }
} }
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let b = self.read.open_simple_record("tuple", Some(0))?; let b = self.open_simple_record("tuple")?;
let result = visitor.visit_unit::<Error>()?; let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?; self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result) Ok(result)
@ -176,7 +199,7 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
let b = self.read.open_simple_record(name, Some(0))?; let b = self.open_simple_record(name)?;
let result = visitor.visit_unit::<Error>()?; let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?; self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result) Ok(result)
@ -186,11 +209,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
match super::value::magic::transmit_input_value( match super::value::magic::transmit_input_value(
name, || Ok(self.read.demand_next(true)?))? name, || Ok(self.read.demand_next(true, &mut IOValueDomainCodec)?))?
{ {
Some(v) => visitor.visit_u64(v), Some(v) => visitor.visit_u64(v),
None => { None => {
let mut b = self.read.open_simple_record(name, Some(1))?; let mut b = self.open_simple_record(name)?;
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?; self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_newtype_struct(&mut *self)?; let result = visitor.visit_newtype_struct(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?; self.read.ensure_complete(b, &B::Item::RecordField)?;
@ -202,23 +225,31 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
// Hack around serde's model: Deserialize *sets* as sequences, // Hack around serde's model: Deserialize *sets* as sequences,
// too, and reconstruct them as Rust Sets on the visitor side. // too, and reconstruct them as Rust Sets on the visitor side.
let i = self.read.open_sequence_or_set()?; let mark = self.read.mark()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), i)) match self.read.open_sequence() {
Ok(()) => visitor.visit_seq(Seq::new(self, B::Type::default(), B::Item::SequenceValue)),
Err(Error::Expected(_)) => {
self.read.restore(&mark)?;
self.read.open_set()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), B::Item::SetValue))
}
Err(e) => Err(e)?
}
} }
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let b = self.read.open_simple_record("tuple", Some(len))?; let b = self.open_simple_record("tuple")?;
let mut seq = Seq::new(self, b, B::Item::RecordField); let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?; let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?; seq.skip_remainder()?;
Ok(result) Ok(result)
} }
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) fn deserialize_tuple_struct<V>(self, name: &'static str, _len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
let b = self.read.open_simple_record(name, Some(len))?; let b = self.open_simple_record(name)?;
let mut seq = Seq::new(self, b, B::Item::RecordField); let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?; let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?; seq.skip_remainder()?;
@ -234,11 +265,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_struct<V>(self, fn deserialize_struct<V>(self,
name: &'static str, name: &'static str,
fields: &'static [&'static str], _fields: &'static [&'static str],
visitor: V) visitor: V)
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
let b = self.read.open_simple_record(name, Some(fields.len()))?; let b = self.open_simple_record(name)?;
let mut seq = Seq::new(self, b, B::Item::RecordField); let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?; let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?; seq.skip_remainder()?;
@ -268,13 +299,13 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
} }
} }
pub struct Seq<'de, 'r, 'a, R: Reader<'de, IOValue>> { pub struct Seq<'de, 'r, 'a, R: Reader<'de>> {
b: B::Type, b: B::Type,
i: B::Item, i: B::Item,
de: &'a mut Deserializer<'de, 'r, R>, de: &'a mut Deserializer<'de, 'r, R>,
} }
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> {
fn new(de: &'a mut Deserializer<'de, 'r, R>, b: B::Type, i: B::Item) -> Self { fn new(de: &'a mut Deserializer<'de, 'r, R>, b: B::Type, i: B::Item) -> Self {
Seq { b, i, de } Seq { b, i, de }
} }
@ -296,7 +327,7 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
} }
} }
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de>> 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) ->
@ -306,7 +337,7 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R
} }
} }
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de>> 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) ->
@ -327,20 +358,20 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R
} }
} }
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> { impl<'de, 'r, 'a, R: Reader<'de>> 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>;
fn variant_seed<V>(self, seed: V) fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{ {
let b = self.read.open_record(None)?; let b = self.open_record()?;
let variant = seed.deserialize(&mut *self)?; let variant = seed.deserialize(&mut *self)?;
Ok((variant, Seq::new(self, b, B::Item::RecordField))) Ok((variant, Seq::new(self, b, B::Item::RecordField)))
} }
} }
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de>> 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

@ -11,15 +11,7 @@ pub enum Error {
CannotDeserializeAny, CannotDeserializeAny,
MissingCloseDelimiter, MissingCloseDelimiter,
MissingItem, MissingItem,
Expected(ExpectedKind, Received), Expected(ExpectedKind),
StreamingSerializationUnsupported,
}
#[derive(Debug)]
pub enum Received {
ReceivedSomethingElse,
ReceivedRecordWithLabel(String),
ReceivedOtherValue(String),
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -35,16 +27,14 @@ pub enum ExpectedKind {
ByteString, ByteString,
Symbol, Symbol,
Record(Option<usize>), Record,
SimpleRecord(String, Option<usize>), SimpleRecord(String),
Sequence, Sequence,
Set, Set,
Dictionary, Dictionary,
Embedded, Embedded,
SequenceOrSet, // Because of hacking up serde's data model: see open_sequence_or_set etc.
Option, Option,
UnicodeScalar, UnicodeScalar,
} }

View File

@ -32,7 +32,10 @@ mod dom {
Value::from(2).wrap()]) Value::from(2).wrap()])
.wrap(); .wrap();
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(), assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]); [0xa8,
0x82, 0xa3, 0x01,
0x85, 0xa5, 255, 255, 255, 255,
0x82, 0xa3, 0x02]);
} }
#[test] fn test_two() { #[test] fn test_two() {
@ -41,7 +44,10 @@ mod dom {
Value::from(2).wrap()]) Value::from(2).wrap()])
.wrap(); .wrap();
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(), assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]); [0xa8,
0x82, 0xa3, 0x01,
0x89, 0xa6, 68, 111, 109, 58, 58, 84, 119, 111,
0x82, 0xa3, 0x02]);
} }
} }
@ -224,9 +230,15 @@ mod value_tests {
#[cfg(test)] #[cfg(test)]
mod decoder_tests { mod decoder_tests {
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;
use crate::error::ExpectedKind;
use crate::error::is_eof_io_error;
use crate::value::BinarySource;
use crate::value::BytesBinarySource;
use crate::value::NestedValue;
use crate::value::Reader;
use crate::value::Value;
fn expect_number_out_of_range<T: core::fmt::Debug>(r: Result<T, Error>) { fn expect_number_out_of_range<T: core::fmt::Debug>(r: Result<T, Error>) {
match r { match r {
@ -239,15 +251,15 @@ mod decoder_tests {
fn expect_expected<T: core::fmt::Debug>(k: ExpectedKind, r: Result<T, Error>) { fn expect_expected<T: core::fmt::Debug>(k: ExpectedKind, r: Result<T, Error>) {
match r { match r {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v), Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
Err(Error::Expected(k1, _)) if k1 == k => (), Err(Error::Expected(k1)) if k1 == k => (),
Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e), Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
} }
} }
#[test] fn skip_annotations_noskip() { #[test] fn skip_annotations_noskip() {
let buf = &b"\x85\x92\x91"[..]; let buf = &b"\xbf\x82\xa3\x01\x82\xa3\x02"[..];
let mut src = BytesBinarySource::new(&buf); let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues()); let mut d = 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());
@ -255,9 +267,9 @@ mod decoder_tests {
} }
#[test] fn skip_annotations_skip() { #[test] fn skip_annotations_skip() {
let buf = &b"\x85\x92\x91"[..]; let buf = &b"\xbf\x82\xa3\x01\x82\xa3\x02"[..];
let mut src = BytesBinarySource::new(&buf); let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues()); let mut d = 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);
@ -265,37 +277,38 @@ 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"\xa8\x87\xa7\x85\xa6Ping\x87\xa7\x85\xa6Pong"[..];
assert_eq!(buf.len(), 16); assert_eq!(buf.len(), 17);
let mut src = BytesBinarySource::new(&buf); let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues()); let mut d = src.packed().iovalues();
assert_eq!(d.reader.source.index, 0); d.reader.open_sequence().unwrap();
assert_eq!(d.reader.source.source.index, 1);
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.source.index, 9);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong")); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
assert_eq!(d.reader.source.index, 16); assert_eq!(d.reader.source.source.index, 17);
assert!(d.next().is_none()); assert!(d.next().is_none());
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false }); assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
} }
#[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"\x91").unwrap(), 1) } #[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"\xa3\x01").unwrap(), 1) }
#[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"\x90").unwrap(), 0) } #[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"\xa3\x00").unwrap(), 0) }
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\x9f").unwrap(), -1) } #[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\xa3\xff").unwrap(), -1) }
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa0\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa3\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"\xa2\xff\xff\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"\xa3\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"\x91").unwrap(), 1) } #[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"\xa3\x01").unwrap(), 1) }
#[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"\x90").unwrap(), 0) } #[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"\xa3\x00").unwrap(), 0) }
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa01").unwrap(), 49) } #[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa31").unwrap(), 49) }
#[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\01").unwrap(), 49) } #[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\01").unwrap(), 49) }
#[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xa9\0\0\0\0\0\0\0\0\01").unwrap(), 49) } #[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\0\0\0\0\0\0\01").unwrap(), 49) }
#[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b"\x9e").unwrap(), -2) } #[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b"\xa3\xfe").unwrap(), -2) }
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa1\xfe\xff").unwrap(), -257) } #[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa3\xfe\xff").unwrap(), -257) }
#[test] fn direct_u8_wrong_format() { #[test] fn direct_u8_wrong_format() {
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xb1\x05bogus")) expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xa6bogus"))
} }
#[test] fn direct_u8_format_b_too_large() { #[test] fn direct_u8_format_b_too_large() {
@ -303,15 +316,15 @@ mod decoder_tests {
} }
#[test] fn direct_i8_format_b_too_large() { #[test] fn direct_i8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i8>(b"\xa1\xfe\xff")) expect_number_out_of_range(from_bytes::<i8>(b"\xa3\xfe\xff"))
} }
#[test] fn direct_i16_format_b_too_large() { #[test] fn direct_i16_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i16>(b"\xa2\xfe\xff\xff")); expect_number_out_of_range(from_bytes::<i16>(b"\xa3\xfe\xff\xff"));
} }
#[test] fn direct_i32_format_b_ok() { #[test] fn direct_i32_format_b_ok() {
assert_eq!(from_bytes::<i32>(b"\xa2\xfe\xff\xff").unwrap(), -65537); assert_eq!(from_bytes::<i32>(b"\xa3\xfe\xff\xff").unwrap(), -65537);
} }
#[test] fn direct_i32_format_b_ok_2() { #[test] fn direct_i32_format_b_ok_2() {
@ -319,50 +332,50 @@ mod decoder_tests {
} }
#[test] fn direct_i64_format_b() { #[test] fn direct_i64_format_b() {
assert_eq!(from_bytes::<i64>(b"\xa0\xff").unwrap(), -1); assert_eq!(from_bytes::<i64>(b"\xa3\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xff\xff").unwrap(), -1); assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1); assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa0\xfe").unwrap(), -2); assert_eq!(from_bytes::<i64>(b"\xa3\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257); assert_eq!(from_bytes::<i64>(b"\xa3\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"\xa2\xfe\xff\xff").unwrap(), -65537); assert_eq!(from_bytes::<i64>(b"\xa3\xfe\xff\xff").unwrap(), -65537);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217); assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
expect_number_out_of_range(from_bytes::<i64>(b"\xa9\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa3\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa8\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa3\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa8\x80\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa3\x80\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa9\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa3\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<i64>(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); assert_eq!(from_bytes::<i64>(b"\xa3\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
assert_eq!(from_bytes::<i64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); assert_eq!(from_bytes::<i64>(b"\xa3\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
assert_eq!(from_bytes::<i64>(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808); assert_eq!(from_bytes::<i64>(b"\xa3\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
assert_eq!(from_bytes::<i64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0); assert_eq!(from_bytes::<i64>(b"\xa3\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\x90").unwrap(), 0); assert_eq!(from_bytes::<i64>(b"\xa3").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); assert_eq!(from_bytes::<i64>(b"\xa3\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
} }
#[test] fn direct_u64_format_b() { #[test] fn direct_u64_format_b() {
expect_number_out_of_range(from_bytes::<u64>(b"\xa0\xff")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\xff"));
assert_eq!(from_bytes::<u64>(b"\xa1\0\xff").unwrap(), 255); assert_eq!(from_bytes::<u64>(b"\xa3\0\xff").unwrap(), 255);
expect_number_out_of_range(from_bytes::<u64>(b"\xa2\xff\xff\xff")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff); assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff);
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa0\x02").unwrap(), 2); assert_eq!(from_bytes::<u64>(b"\xa3\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"\xa2\x00\x01\x00").unwrap(), 256); assert_eq!(from_bytes::<u64>(b"\xa3\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"\xa2\x01\x00\x00").unwrap(), 65536); assert_eq!(from_bytes::<u64>(b"\xa3\x01\x00\x00").unwrap(), 65536);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216); assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000); assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa8\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); assert_eq!(from_bytes::<u64>(b"\xa3\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"\xa8\x7f\xf2\x00\x00\x00\x00\x00\x00\x00")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); assert_eq!(from_bytes::<u64>(b"\xa3\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); assert_eq!(from_bytes::<u64>(b"\xa3\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
expect_number_out_of_range(from_bytes::<u64>(b"\xa7\x80\0\0\0\0\0\0\0")); expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x80\0\0\0\0\0\0\0"));
assert_eq!(from_bytes::<u64>(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808); assert_eq!(from_bytes::<u64>(b"\xa3\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
assert_eq!(from_bytes::<u64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0); assert_eq!(from_bytes::<u64>(b"\xa3\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\x90").unwrap(), 0); assert_eq!(from_bytes::<u64>(b"\xa3").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); assert_eq!(from_bytes::<u64>(b"\xa3\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
} }
} }
@ -371,7 +384,7 @@ mod serde_tests {
use crate::symbol::Symbol; use crate::symbol::Symbol;
use crate::de::from_bytes as deserialize_from_bytes; use crate::de::from_bytes as deserialize_from_bytes;
use crate::value::de::from_value as deserialize_from_value; use crate::value::de::from_value as deserialize_from_value;
use crate::value::to_value; use crate::value::{to_value, BinarySource, BytesBinarySource, Reader};
use crate::value::{Value, IOValue, Map, Set}; use crate::value::{Value, IOValue, Map, Set};
use crate::value::packed::PackedWriter; use crate::value::packed::PackedWriter;
@ -426,51 +439,51 @@ mod serde_tests {
assert_eq!(v, x); assert_eq!(v, x);
let expected_bytes = vec![ let expected_bytes = vec![
0xb4, // Struct 0xa7, // Record
0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue 0x8c, 0xa6, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello" 0x87, 0xa4, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, // "hello"
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1 0x85, 0xa6, 0x73, 0x79, 0x6d, 0x31, // sym1
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2 0x85, 0xa6, 0x73, 0x79, 0x6d, 0x32, // sym2
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3 0x85, 0xa6, 0x73, 0x79, 0x6d, 0x33, // sym3
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4 0x85, 0xa6, 0x73, 0x79, 0x6d, 0x34, // sym4
0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world" 0x87, 0xa4, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x00, // "world"
0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice" 0x86, 0xa5, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec" 0x84, 0xa5, 0x76, 0x65, 0x63, // #"vec"
0xb5, // Sequence 0x89, 0xa8, // Sequence
0x80, // false 0x81, 0xa0, // #f
0x81, // true 0x81, 0xa1, // #t
0x80, // false 0x81, 0xa0, // #f
0x81, // true 0x81, 0xa1, // #t
0x84, 0x95, 0xa9, // Set
0xb6, // Set 0x85, 0xa4, 0x6f, 0x6e, 0x65, 0x00, // "one"
0xb1, 0x03, 0x6f, 0x6e, 0x65, 0x87, 0xa4, 0x74, 0x68, 0x72, 0x65, 0x65, 0x00, // "three"
0xb1, 0x03, 0x74, 0x77, 0x6f, 0x85, 0xa4, 0x74, 0x77, 0x6f, 0x00, // "two"
0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65, 0x83, 0xa3, 0x30, 0x39, // 12345
0x84, 0x84, 0xa4, 0x68, 0x69, 0x00, // "hi"
0xa1, 0x30, 0x39, // 12345
0xb1, 0x02, 0x68, 0x69, // "hi"
0xb7, // Dictionary
0xb1, 0x03, 0x72, 0x65, 0x64, // "red"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84,
0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0x90, 0xa1, 0x00, 0xff, 0x84,
0xb1, 0x05, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0xa1, 0x00, 0xff, 0x90, 0x84,
0x84,
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345, 0xcc, 0xaa, // Dictionary
0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789 0x86, 0xa4, 0x62, 0x6c, 0x75, 0x65, 0x00, // "blue"
0x84, 0x91, 0xa7, 0x87, 0xa6, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x81, 0xa3, 0x81, 0xa3, 0x83, 0xa3, 0x00, 0xff,
0x87, 0xa4, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x00, // "green"
0x91, 0xa7, 0x87, 0xa6, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x81, 0xa3, 0x83, 0xa3, 0x00, 0xff, 0x81, 0xa3,
0x85, 0xa4, 0x72, 0x65, 0x64, 0x00, // "red"
0x91, 0xa7, 0x87, 0xa6, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x83, 0xa3, 0x00, 0xff, 0x81, 0xa3, 0x81, 0xa3,
0x85, 0xa2, 0x41, 0x45, 0x85, 0x1f, // 12.345
0x89, 0xa2, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2 // 12.3456789
]; ];
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let v_bytes_1 = PackedWriter::encode_iovalue(&w).unwrap(); let v_bytes_1 = PackedWriter::encode_iovalue(&w).unwrap();
println!("== w bytes = {:?}", v_bytes_1); println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1); assert_eq!(expected_bytes, v_bytes_1);
let z = BytesBinarySource::new(&v_bytes_1).packed().iovalues().demand_next().unwrap();
println!("== z: {:#?}", &z);
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let mut v_bytes_2 = Vec::new(); let mut v_bytes_2 = Vec::new();
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap(); v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
println!("== v bytes = {:?}", v_bytes_2); println!("== v bytes = {:?}", v_bytes_2);

View File

@ -1,7 +1,7 @@
use serde::Serialize; use serde::Serialize;
use super::value::IOValueDomainCodec; use super::value::IOValueDomainCodec;
use super::value::boundary as B; use super::value::boundary as B;
use super::value::writer::{Writer, CompoundWriter}; use super::value::writer::Writer;
pub use super::error::Error; pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>; type Result<T> = std::result::Result<T, Error>;
@ -17,22 +17,21 @@ impl<'w, W: Writer> Serializer<'w, W> {
} }
} }
enum SequenceVariant<W: Writer> { enum SequenceVariant {
Sequence(W::SeqWriter), Sequence,
Record(W::RecWriter), Record,
} }
pub struct SerializeCompound<'a, 'w, W: Writer> { pub struct SerializeCompound<'a, 'w, W: Writer> {
b: B::Type, b: B::Type,
i: B::Item, i: B::Item,
ser: &'a mut Serializer<'w, W>, ser: &'a mut Serializer<'w, W>,
c: SequenceVariant<W>, variant: SequenceVariant,
} }
pub struct SerializeDictionary<'a, 'w, W: Writer> { pub struct SerializeDictionary<'a, 'w, W: Writer> {
b: B::Type, b: B::Type,
ser: &'a mut Serializer<'w, W>, ser: &'a mut Serializer<'w, W>,
d: W::DictWriter,
} }
impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> { impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
@ -91,13 +90,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
} }
fn serialize_char(self, v: char) -> Result<Self::Ok> { fn serialize_char(self, v: char) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(1))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("UnicodeScalar")?; self.write.write_symbol("UnicodeScalar")?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?; self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
c.write_u32(v as u32)?; self.write.write_u32(v as u32)?;
c.boundary(&B::end(B::Item::RecordField))?; self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_str(self, v: &str) -> Result<Self::Ok> { fn serialize_str(self, v: &str) -> Result<Self::Ok> {
@ -109,37 +108,37 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
} }
fn serialize_none(self) -> Result<Self::Ok> { fn serialize_none(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("None")?; self.write.write_symbol("None")?;
c.boundary(&B::end(B::Item::RecordLabel))?; self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize { fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
let mut c = self.write.start_record(Some(1))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("Some")?; self.write.write_symbol("Some")?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?; self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, v)?; to_writer(self.write, v)?;
c.boundary(&B::end(B::Item::RecordField))?; self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_unit(self) -> Result<Self::Ok> { fn serialize_unit(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("tuple")?; self.write.write_symbol("tuple")?;
c.boundary(&B::end(B::Item::RecordLabel))?; self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> { fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?; self.write.write_symbol(name)?;
c.boundary(&B::end(B::Item::RecordLabel))?; self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_unit_variant(self, fn serialize_unit_variant(self,
@ -148,11 +147,11 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
variant_name: &'static str) -> variant_name: &'static str) ->
Result<Self::Ok> Result<Self::Ok>
{ {
let mut c = self.write.start_record(Some(0))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; self.write.write_symbol(variant_name)?;
c.boundary(&B::end(B::Item::RecordLabel))?; self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
@ -162,13 +161,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?), Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
None => { None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`? // TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(Some(1))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?; self.write.write_symbol(name)?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?; self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, value)?; to_writer(self.write, value)?;
c.boundary(&B::end(B::Item::RecordField))?; self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
} }
} }
@ -180,72 +179,72 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
value: &T) -> value: &T) ->
Result<Self::Ok> where T: Serialize Result<Self::Ok> where T: Serialize
{ {
let mut c = self.write.start_record(Some(1))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; self.write.write_symbol(variant_name)?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?; self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, value)?; to_writer(self.write, value)?;
c.boundary(&B::end(B::Item::RecordField))?; self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?) Ok(self.write.end_record()?)
} }
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> { fn serialize_seq(self, _count: Option<usize>) -> Result<Self::SerializeSeq> {
let c = self.write.start_sequence(count)?; self.write.start_sequence()?;
Ok(SerializeCompound::seq(self, c)) Ok(SerializeCompound::seq(self))
} }
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> { fn serialize_tuple(self, _count: usize) -> Result<Self::SerializeTuple> {
let mut c = self.write.start_record(Some(count))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("tuple")?; self.write.write_symbol("tuple")?;
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self))
} }
fn serialize_tuple_struct(self, name: &'static str, count: usize) -> fn serialize_tuple_struct(self, name: &'static str, _count: usize) ->
Result<Self::SerializeTupleStruct> Result<Self::SerializeTupleStruct>
{ {
let mut c = self.write.start_record(Some(count))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?; self.write.write_symbol(name)?;
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self))
} }
fn serialize_tuple_variant(self, fn serialize_tuple_variant(self,
_name: &'static str, _name: &'static str,
_variant: u32, _variant: u32,
variant_name: &'static str, variant_name: &'static str,
count: usize) -> _count: usize) ->
Result<Self::SerializeTupleVariant> Result<Self::SerializeTupleVariant>
{ {
let mut c = self.write.start_record(Some(count))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; self.write.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self))
} }
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> { fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
let d = self.write.start_dictionary(count)?; self.write.start_dictionary()?;
Ok(SerializeDictionary { b: B::Type::default(), ser: self, d }) Ok(SerializeDictionary { b: B::Type::default(), ser: self })
} }
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> { fn serialize_struct(self, name: &'static str, _count: usize) -> Result<Self::SerializeStruct> {
let mut c = self.write.start_record(Some(count))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?; self.write.write_symbol(name)?;
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self))
} }
fn serialize_struct_variant(self, fn serialize_struct_variant(self,
_name: &'static str, _name: &'static str,
_variant: u32, _variant: u32,
variant_name: &'static str, variant_name: &'static str,
count: usize) -> _count: usize) ->
Result<Self::SerializeStructVariant> Result<Self::SerializeStructVariant>
{ {
let mut c = self.write.start_record(Some(count))?; self.write.start_record()?;
c.boundary(&B::start(B::Item::RecordLabel))?; self.write.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; self.write.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self))
} }
} }
@ -255,42 +254,42 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize { fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
self.b.opening = Some(B::Item::DictionaryKey); self.b.opening = Some(B::Item::DictionaryKey);
self.d.boundary(&self.b)?; self.ser.write.boundary(&self.b)?;
to_writer(&mut self.d, key)?; to_writer(self.ser.write, key)?;
self.b.shift(None); self.b.shift(None);
Ok(()) Ok(())
} }
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
self.b.opening = Some(B::Item::DictionaryValue); self.b.opening = Some(B::Item::DictionaryValue);
self.d.boundary(&self.b)?; self.ser.write.boundary(&self.b)?;
to_writer(&mut self.d, value)?; to_writer(self.ser.write, value)?;
self.b.shift(None); self.b.shift(None);
Ok(()) Ok(())
} }
fn end(mut self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
self.d.boundary(&self.b)?; self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_dictionary(self.d)?) Ok(self.ser.write.end_dictionary()?)
} }
} }
impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> { impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
fn seq(ser: &'a mut Serializer<'w, W>, c: W::SeqWriter) -> Self { fn seq(ser: &'a mut Serializer<'w, W>) -> Self {
SerializeCompound { SerializeCompound {
b: B::Type::default(), b: B::Type::default(),
i: B::Item::SequenceValue, i: B::Item::SequenceValue,
ser, ser,
c: SequenceVariant::Sequence(c), variant: SequenceVariant::Sequence,
} }
} }
fn rec(ser: &'a mut Serializer<'w, W>, c: W::RecWriter) -> Self { fn rec(ser: &'a mut Serializer<'w, W>) -> Self {
SerializeCompound { SerializeCompound {
b: B::end(B::Item::RecordLabel), b: B::end(B::Item::RecordLabel),
i: B::Item::RecordField, i: B::Item::RecordField,
ser, ser,
c: SequenceVariant::Record(c), variant: SequenceVariant::Record,
} }
} }
@ -298,23 +297,21 @@ impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
where T: Serialize where T: Serialize
{ {
self.b.opening = Some(self.i.clone()); self.b.opening = Some(self.i.clone());
match &mut self.c { self.ser.write.boundary(&self.b)?;
SequenceVariant::Sequence(w) => { w.boundary(&self.b)?; to_writer(w, value)?; } to_writer(self.ser.write, value)?;
SequenceVariant::Record(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
}
self.b.shift(None); self.b.shift(None);
Ok(()) Ok(())
} }
fn complete(self) -> Result<()> { fn complete(self) -> Result<()> {
match self.c { match self.variant {
SequenceVariant::Sequence(mut w) => { SequenceVariant::Sequence => {
w.boundary(&self.b)?; self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_sequence(w)?) Ok(self.ser.write.end_sequence()?)
} }
SequenceVariant::Record(mut w) => { SequenceVariant::Record => {
w.boundary(&self.b)?; self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_record(w)?) Ok(self.ser.write.end_record()?)
} }
} }
} }

View File

@ -1,6 +1,6 @@
use crate::value::repr::{Float, Double}; use crate::value::repr::{Float, Double};
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map}; use crate::value::{Value, NestedValue, IOValue, Map};
use crate::error::{Error, ExpectedKind, Received}; use crate::error::Error;
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::iter::Iterator; use std::iter::Iterator;
@ -11,7 +11,7 @@ pub struct Deserializer<'de> {
input: &'de IOValue, input: &'de IOValue,
} }
pub fn from_value<'a, T>(v: &'a IOValue) -> Result<T> where T: Deserialize<'a> pub fn from_value<'de, T>(v: &'de IOValue) -> Result<T> where T: Deserialize<'de>
{ {
let mut de = Deserializer::from_value(v); let mut de = Deserializer::from_value(v);
let t = T::deserialize(&mut de)?; let t = T::deserialize(&mut de)?;
@ -22,13 +22,6 @@ impl<'de> Deserializer<'de> {
pub fn from_value(v: &'de IOValue) -> Self { pub fn from_value(v: &'de IOValue) -> Self {
Deserializer { input: v } Deserializer { input: v }
} }
fn check<'a, T, F>(&'a mut self, f: F, k: ExpectedKind) -> Result<T>
where F: FnOnce(&'de UnwrappedIOValue) -> Option<T>
{
f(self.input.value()).ok_or_else(
|| Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.input))))
}
} }
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de> impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
@ -42,7 +35,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
Value::Boolean(b) => visitor.visit_bool(*b), Value::Boolean(b) => visitor.visit_bool(*b),
Value::Float(Float(f)) => visitor.visit_f32(*f), Value::Float(Float(f)) => visitor.visit_f32(*f),
Value::Double(Double(d)) => visitor.visit_f64(*d), Value::Double(Double(d)) => visitor.visit_f64(*d),
Value::String(ref s) => visitor.visit_str(&s), Value::String(s) => visitor.visit_str(&s),
Value::ByteString(_) => self.deserialize_bytes(visitor), Value::ByteString(_) => self.deserialize_bytes(visitor),
Value::Record(_) => Value::Record(_) =>
if v.is_simple_record("tuple", Some(0)) { if v.is_simple_record("tuple", Some(0)) {
@ -139,8 +132,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let s: &'de str = &self.input.value().to_string()?; visitor.visit_borrowed_str(self.input.value().to_string()?)
visitor.visit_borrowed_str(s)
} }
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
@ -150,8 +142,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let bs: &'de [u8] = &self.input.value().to_bytestring()?; visitor.visit_borrowed_bytes(self.input.value().to_bytestring()?)
visitor.visit_borrowed_bytes(bs)
} }
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
@ -293,7 +284,7 @@ pub struct DictMap<'a, 'de: 'a> {
impl<'de, 'a> DictMap<'a, 'de> { impl<'de, 'a> DictMap<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self { fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self {
DictMap{ pending: None, iter: Box::new(d.iter()), de } DictMap { pending: None, iter: Box::new(d.iter()), de }
} }
} }
@ -328,7 +319,7 @@ impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
fn variant_seed<V>(self, seed: V) fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{ {
let r = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?; let r = self.input.value().to_record(None)?;
let v = self.input; let v = self.input;
self.input = r.label(); self.input = r.label();
let variant = seed.deserialize(&mut *self)?; let variant = seed.deserialize(&mut *self)?;
@ -345,7 +336,7 @@ impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
} }
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> { fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
let r = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?; let r = self.input.value().to_record(Some(1))?;
self.input = &r.fields()[0]; self.input = &r.fields()[0];
seed.deserialize(&mut *self) seed.deserialize(&mut *self)
} }

View File

@ -1,24 +1,14 @@
use std::io; use std::io;
use super::BinarySource;
use super::BytesBinarySource;
use super::Embeddable; use super::Embeddable;
use super::IOValue; use super::IOValue;
use super::Reader; use super::Reader;
use super::Writer; use super::Writer;
use super::packed;
pub trait DomainParse<D: Embeddable> {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D>;
}
pub trait DomainDecode<D: Embeddable> { pub trait DomainDecode<D: Embeddable> {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>( fn decode_embedded<'de, 'r, R: Reader<'de>>(
&mut self, &mut self,
src: &'src mut S, r: &'r mut R,
read_annotations: bool, read_annotations: bool,
) -> io::Result<D>; ) -> io::Result<D>;
} }
@ -31,34 +21,15 @@ pub trait DomainEncode<D: Embeddable> {
) -> io::Result<()>; ) -> io::Result<()>;
} }
impl<'a, D: Embeddable, T: DomainParse<D>> DomainParse<D> for &'a mut T {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D> {
(**self).parse_embedded(v)
}
}
impl<'a, D: Embeddable, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
read_annotations: bool,
) -> io::Result<D> {
(**self).decode_embedded(src, read_annotations)
}
}
pub struct IOValueDomainCodec; pub struct IOValueDomainCodec;
impl DomainDecode<IOValue> for IOValueDomainCodec { impl DomainDecode<IOValue> for IOValueDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>( fn decode_embedded<'de, 'r, R: Reader<'de>>(
&mut self, &mut self,
src: &'src mut S, r: &'r mut R,
read_annotations: bool, read_annotations: bool,
) -> io::Result<IOValue> { ) -> io::Result<IOValue> {
packed::PackedReader::new(src, IOValueDomainCodec).demand_next(read_annotations) r.demand_next(read_annotations, self)
} }
} }
@ -75,9 +46,9 @@ impl DomainEncode<IOValue> for IOValueDomainCodec {
pub struct NoEmbeddedDomainCodec; pub struct NoEmbeddedDomainCodec;
impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec { impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>( fn decode_embedded<'de, 'r, R: Reader<'de>>(
&mut self, &mut self,
_src: &'src mut S, _r: &'r mut R,
_read_annotations: bool, _read_annotations: bool,
) -> io::Result<D> { ) -> io::Result<D> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
@ -93,32 +64,3 @@ impl<D: Embeddable> DomainEncode<D> for NoEmbeddedDomainCodec {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
} }
} }
pub struct ViaCodec<C>(C);
impl<C> ViaCodec<C> {
pub fn new(c: C) -> Self {
ViaCodec(c)
}
}
impl<D: Embeddable, C: DomainDecode<D>> DomainParse<D> for ViaCodec<C> {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D> {
let bs = packed::PackedWriter::encode_iovalue(v)?;
self.0.decode_embedded(&mut BytesBinarySource::new(&bs), true)
}
}
impl<D: Embeddable, C: DomainParse<D>> DomainDecode<D> for ViaCodec<C> {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
read_annotations: bool,
) -> io::Result<D> {
let v = src.packed(IOValueDomainCodec).demand_next(read_annotations)?;
self.0.parse_embedded(&v)
}
}

View File

@ -0,0 +1,85 @@
use std::borrow::Cow;
use std::cell::RefCell;
use std::io;
#[derive(Eq, Debug)]
pub struct IOList {
chunks: RefCell<Vec<Vec<u8>>>,
len: usize,
}
impl IOList {
pub fn new() -> Self {
IOList {
chunks: RefCell::new(Vec::new()),
len: 0,
}
}
fn rightmost_chunk(&mut self) -> &mut Vec<u8> {
let cs = self.chunks.get_mut();
if cs.is_empty() {
cs.push(Vec::new());
}
cs.last_mut().unwrap()
}
fn consolidate(&self) {
if self.chunks.borrow().len() != 1 {
let bs = self.chunks.replace(Vec::new()).concat();
self.chunks.borrow_mut().push(bs);
}
}
pub fn len(&mut self) -> usize {
self.len
}
pub fn write(&mut self, b: u8) {
self.rightmost_chunk().push(b);
self.len += 1;
}
#[inline(always)]
pub fn write_all(&mut self, cow: Cow<'_, [u8]>) {
self.len += cow.len();
match cow {
Cow::Borrowed(bs) => self.chunks.get_mut().push(bs.to_owned()),
Cow::Owned(bs) => self.chunks.get_mut().push(bs),
}
}
pub fn append(&mut self, mut iol: IOList) {
self.len += iol.len();
self.chunks.get_mut().append(&mut iol.chunks.take());
}
pub fn write_to<W: io::Write>(self, mut w: W) -> io::Result<()> {
for chunk in self.chunks.take() {
w.write_all(&chunk)?;
}
Ok(())
}
}
impl std::cmp::PartialEq for IOList {
fn eq(&self, other: &Self) -> bool {
self.consolidate();
other.consolidate();
self.chunks.borrow().last().unwrap() == other.chunks.borrow().last().unwrap()
}
}
impl std::cmp::Ord for IOList {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.consolidate();
other.consolidate();
self.chunks.borrow().last().unwrap().cmp(other.chunks.borrow().last().unwrap())
}
}
impl std::cmp::PartialOrd for IOList {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

View File

@ -1,12 +1,14 @@
pub mod boundary; pub mod boundary;
pub mod de; pub mod de;
pub mod domain; pub mod domain;
pub mod iolist;
pub mod magic; pub mod magic;
pub mod packed; pub mod packed;
pub mod reader; pub mod reader;
pub mod repr; pub mod repr;
pub mod ser; pub mod ser;
pub mod signed_integer; pub mod signed_integer;
pub mod source;
pub mod suspendable; pub mod suspendable;
pub mod text; pub mod text;
pub mod writer; pub mod writer;
@ -16,17 +18,12 @@ pub use de::Deserializer;
pub use de::from_value; pub use de::from_value;
pub use domain::DomainDecode; pub use domain::DomainDecode;
pub use domain::DomainEncode; pub use domain::DomainEncode;
pub use domain::DomainParse;
pub use domain::IOValueDomainCodec; pub use domain::IOValueDomainCodec;
pub use domain::NoEmbeddedDomainCodec; pub use domain::NoEmbeddedDomainCodec;
pub use domain::ViaCodec;
pub use merge::merge; pub use merge::merge;
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 reader::Token; pub use reader::Token;
pub use repr::AnnotatedValue; pub use repr::AnnotatedValue;
@ -50,6 +47,9 @@ pub use repr::Value;
pub use repr::ValueClass; pub use repr::ValueClass;
pub use ser::Serializer; pub use ser::Serializer;
pub use ser::to_value; pub use ser::to_value;
pub use source::BinarySource;
pub use source::BytesBinarySource;
pub use source::IOBinarySource;
pub use text::TextReader; pub use text::TextReader;
pub use text::TextWriter; pub use text::TextWriter;
pub use writer::Writer; pub use writer::Writer;

View File

@ -6,12 +6,6 @@ pub enum Tag {
False, False,
True, True,
Float, Float,
Double,
End,
Annotation,
Embedded,
SmallInteger(i8),
MediumInteger(u8),
SignedInteger, SignedInteger,
String, String,
ByteString, ByteString,
@ -20,6 +14,8 @@ pub enum Tag {
Sequence, Sequence,
Set, Set,
Dictionary, Dictionary,
Embedded,
Annotation,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
@ -41,24 +37,19 @@ impl TryFrom<u8> for Tag {
type Error = InvalidTag; type Error = InvalidTag;
fn try_from(v: u8) -> Result<Self, Self::Error> { fn try_from(v: u8) -> Result<Self, Self::Error> {
match v { match v {
0x80 => Ok(Self::False), 0xa0 => Ok(Self::False),
0x81 => Ok(Self::True), 0xa1 => Ok(Self::True),
0x82 => Ok(Self::Float), 0xa2 => Ok(Self::Float),
0x83 => Ok(Self::Double), 0xa3 => Ok(Self::SignedInteger),
0x84 => Ok(Self::End), 0xa4 => Ok(Self::String),
0x85 => Ok(Self::Annotation), 0xa5 => Ok(Self::ByteString),
0x86 => Ok(Self::Embedded), 0xa6 => Ok(Self::Symbol),
0x90..=0x9c => Ok(Self::SmallInteger((v - 0x90) as i8)), 0xa7 => Ok(Self::Record),
0x9d..=0x9f => Ok(Self::SmallInteger((v - 0x90) as i8 - 16)), 0xa8 => Ok(Self::Sequence),
0xa0..=0xaf => Ok(Self::MediumInteger(v - 0xa0 + 1)), 0xa9 => Ok(Self::Set),
0xb0 => Ok(Self::SignedInteger), 0xaa => Ok(Self::Dictionary),
0xb1 => Ok(Self::String), 0xab => Ok(Self::Embedded),
0xb2 => Ok(Self::ByteString), 0xbf => Ok(Self::Annotation),
0xb3 => Ok(Self::Symbol),
0xb4 => Ok(Self::Record),
0xb5 => Ok(Self::Sequence),
0xb6 => Ok(Self::Set),
0xb7 => Ok(Self::Dictionary),
_ => Err(InvalidTag(v)) _ => Err(InvalidTag(v))
} }
} }
@ -67,23 +58,19 @@ impl TryFrom<u8> for Tag {
impl From<Tag> for u8 { impl From<Tag> for u8 {
fn from(v: Tag) -> Self { fn from(v: Tag) -> Self {
match v { match v {
Tag::False => 0x80, Tag::False => 0xa0,
Tag::True => 0x81, Tag::True => 0xa1,
Tag::Float => 0x82, Tag::Float => 0xa2,
Tag::Double => 0x83, Tag::SignedInteger => 0xa3,
Tag::End => 0x84, Tag::String => 0xa4,
Tag::Annotation => 0x85, Tag::ByteString => 0xa5,
Tag::Embedded => 0x86, Tag::Symbol => 0xa6,
Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 }, Tag::Record => 0xa7,
Tag::MediumInteger(count) => count - 1 + 0xa0, Tag::Sequence => 0xa8,
Tag::SignedInteger => 0xb0, Tag::Set => 0xa9,
Tag::String => 0xb1, Tag::Dictionary => 0xaa,
Tag::ByteString => 0xb2, Tag::Embedded => 0xab,
Tag::Symbol => 0xb3, Tag::Annotation => 0xbf,
Tag::Record => 0xb4,
Tag::Sequence => 0xb5,
Tag::Set => 0xb6,
Tag::Dictionary => 0xb7,
} }
} }
} }

View File

@ -11,22 +11,22 @@ use super::{BinarySource, DomainDecode, IOValue, IOValueDomainCodec, NestedValue
pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>( pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8], bs: &[u8],
decode_embedded: Dec, decode_embedded: &mut Dec,
) -> io::Result<N> { ) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(false) super::BytesBinarySource::new(bs).packed().demand_next(false, decode_embedded)
} }
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> { pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
from_bytes(bs, IOValueDomainCodec) from_bytes(bs, &mut IOValueDomainCodec)
} }
pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>( pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8], bs: &[u8],
decode_embedded: Dec, decode_embedded: &mut Dec,
) -> io::Result<N> { ) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(true) super::BytesBinarySource::new(bs).packed().demand_next(true, decode_embedded)
} }
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> { pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
annotated_from_bytes(bs, IOValueDomainCodec) annotated_from_bytes(bs, &mut IOValueDomainCodec)
} }

View File

@ -1,4 +1,4 @@
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error}; use crate::error::{self, ExpectedKind, io_eof, io_syntax_error};
use num::bigint::BigInt; use num::bigint::BigInt;
use num::traits::cast::{FromPrimitive, ToPrimitive}; use num::traits::cast::{FromPrimitive, ToPrimitive};
@ -6,6 +6,7 @@ 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;
use std::fmt::Debug;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -15,6 +16,7 @@ use super::super::{
DomainDecode, DomainDecode,
Map, Map,
NestedValue, NestedValue,
NoEmbeddedDomainCodec,
Record, Record,
Set, Set,
Value, Value,
@ -22,116 +24,294 @@ use super::super::{
boundary as B, boundary as B,
reader::{ reader::{
Token, Token,
BinarySource,
Reader, Reader,
ReaderResult, ReaderResult,
}, },
repr::Annotations,
signed_integer::SignedInteger, signed_integer::SignedInteger,
source::BinarySource,
}; };
pub struct PackedReader<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> { #[derive(Debug)]
pub source: &'src mut S, enum Continuation {
pub decode_embedded: Dec, Skip { count: Option<u64> },
phantom: PhantomData<&'de N>, Sequence { count: Option<u64> },
} }
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> pub struct PackedReaderSource<'de, 'src, S: BinarySource<'de>> {
BinarySource<'de> pub source: &'src mut S,
for PackedReader<'de, 'src, N, Dec, S> stack: Vec<Continuation>,
{ count: Option<u64>,
type Mark = S::Mark; expect_length: bool,
phantom: PhantomData<&'de ()>,
}
// TODO: inline PackedReaderSource.
pub struct PackedReader<'de, 'src, S: BinarySource<'de>> {
pub source: PackedReaderSource<'de, 'src, S>,
}
pub struct ReaderMark<SourceMark> {
source_mark: SourceMark,
stack_len: usize,
count: Option<u64>,
expect_length: bool,
}
impl<'de, 'src, S: BinarySource<'de>> PackedReaderSource<'de, 'src, S> {
fn advance(&mut self, delta: u64) -> bool {
if let Some(ref mut c) = self.count {
if *c < delta {
return false;
}
*c -= delta;
}
return true;
}
fn advance_or_eof(&mut self, delta: u64) -> io::Result<()> {
if self.advance(delta) { Ok(()) } else { Err(io_eof()) }
}
pub fn set_expected_count(&mut self, expected_count: u64) {
match self.count {
Some(n) =>
panic!("Attempt to set_expected_count to {} when count already {}",
expected_count,
n),
None =>
self.count = Some(expected_count),
}
}
#[inline(always)]
fn peek_noeof(&mut self) -> io::Result<u8> {
self.peek()?.ok_or_else(|| io_eof())
}
#[inline(always)]
fn read(&mut self) -> io::Result<u8> {
let v = self.peek_noeof()?;
self.skip()?;
Ok(v)
}
#[inline(always)]
fn varint(&mut self) -> io::Result<u64> {
let mut acc = self.read()? as u64;
if acc & 0x80 != 0 { return Ok(acc - 0x80) }
loop {
if acc & 0xfe0000000000000 != 0 {
return Err(io_syntax_error("Varint length marker overflow"));
}
acc <<= 7;
let v = self.read()? as u64;
if v & 0x80 != 0 { return Ok(acc + v - 0x80) }
acc += v;
}
}
fn narrow_to_len(&mut self) -> io::Result<Option<u64>> {
let item_len = self.varint()?;
if !self.advance(item_len) {
return Err(io_syntax_error("Bad item length"));
}
let remaining = self.count;
self.count = Some(item_len);
Ok(remaining)
}
fn narrow(&mut self) -> io::Result<()> {
if !self.expect_length {
self.expect_length = true; // after the first value, always true!
} else {
let count = self.narrow_to_len()?;
self.stack.push(Continuation::Sequence { count });
}
Ok(())
}
fn narrow_to_annotated_value(&mut self) -> io::Result<()> {
let count = self.narrow_to_len()?;
self.stack.push(Continuation::Skip { count });
Ok(())
}
fn widen<R: Debug>(&mut self, r: R) -> io::Result<R> {
loop {
match self.stack.pop() {
None => break,
Some(Continuation::Skip { count }) => match count {
Some(n) => self.source.discard(n)?,
None => { self.source.read_to_end()?; }
}
Some(Continuation::Sequence { count }) => {
self.count = count;
break;
}
}
}
Ok(r)
}
#[inline(always)]
fn read_signed_integer(&mut self) -> io::Result<SignedInteger> {
match self.count {
Some(0) => Ok(SignedInteger::from(0_i128)),
Some(1) => Ok(SignedInteger::from(self.read()? as i8)),
None | Some(_) => self.read_long_signed_integer()
}
}
fn read_long_signed_integer(&mut self) -> io::Result<SignedInteger> {
let bs = self.read_to_end()?;
let count = bs.len();
if count == 0 {
Ok(SignedInteger::from(0_i128))
} else if (bs[0] & 0x80) == 0 {
// Positive or zero.
let mut i = 0;
while i < count && bs[i] == 0 { i += 1; }
if count - i <= 16 {
let mut buf = [0; 16];
buf[16 - (count - i)..].copy_from_slice(&bs[i..]);
Ok(SignedInteger::from(u128::from_be_bytes(buf)))
} else {
Ok(SignedInteger::from(
Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..]))))
}
} else {
// Negative.
let mut i = 0;
while i < count && bs[i] == 0xff { i += 1; }
if count - i <= 16 {
let mut buf = [0xff; 16];
buf[16 - (count - i)..].copy_from_slice(&bs[i..]);
Ok(SignedInteger::from(i128::from_be_bytes(buf)))
} else {
Ok(SignedInteger::from(
Cow::Owned(BigInt::from_signed_bytes_be(&bs))))
}
}
}
}
impl<'de, 'src, S: BinarySource<'de>> BinarySource<'de> for PackedReaderSource<'de, 'src, S> {
type Mark = ReaderMark<S::Mark>;
#[inline(always)] #[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> { fn mark(&mut self) -> io::Result<Self::Mark> {
self.source.mark() Ok(ReaderMark {
source_mark: self.source.mark()?,
stack_len: self.stack.len(),
count: self.count,
expect_length: self.expect_length,
})
} }
#[inline(always)] #[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> { fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.source.restore(mark) let ReaderMark { source_mark, stack_len, count, expect_length } = mark;
if *stack_len > self.stack.len() {
panic!("Attempt to restore state to longer stack ({}) than exists ({})",
stack_len,
self.stack.len());
}
self.stack.truncate(*stack_len);
self.source.restore(source_mark)?;
self.count = *count;
self.expect_length = *expect_length;
Ok(())
} }
#[inline(always)] #[inline(always)]
fn skip(&mut self) -> io::Result<()> { fn skip(&mut self) -> io::Result<()> {
self.advance_or_eof(1)?;
self.source.skip() self.source.skip()
} }
#[inline(always)] #[inline(always)]
fn peek(&mut self) -> io::Result<u8> { fn peek(&mut self) -> io::Result<Option<u8>> {
self.source.peek() match self.count {
Some(0) => Ok(None),
_ => self.source.peek(),
}
} }
#[inline(always)] #[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> { fn discard(&mut self, count: u64) -> io::Result<()> {
self.advance_or_eof(count)?;
self.source.discard(count)
}
#[inline(always)]
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
self.advance_or_eof(count)?;
self.source.readbytes(count) self.source.readbytes(count)
} }
#[inline(always)] #[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> { fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
self.advance_or_eof(bs.len() as u64)?;
self.source.readbytes_into(bs) self.source.readbytes_into(bs)
} }
#[inline(always)]
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
match self.count {
Some(n) => self.readbytes(n),
None => self.source.read_to_end(),
}
}
} }
fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error { fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
error::Error::NumberOutOfRange(i.into()) error::Error::NumberOutOfRange(i.into())
} }
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> PackedReader<'de, 'src, N, Dec, S> { impl<'de, 'src, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
#[inline(always)] #[inline(always)]
pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self { pub fn new(source: &'src mut S) -> Self {
PackedReader { source, decode_embedded, phantom: PhantomData } PackedReader {
source: PackedReaderSource {
source,
stack: Vec::new(),
count: None,
expect_length: false,
phantom: PhantomData,
},
}
} }
#[inline(always)] #[inline(always)]
fn read(&mut self) -> io::Result<u8> { fn peek_tag(&mut self) -> io::Result<Tag> {
let v = self.peek()?; Ok(Tag::try_from(self.source.peek_noeof()?)?)
self.skip()?; }
Ok(v)
#[inline(always)]
fn read_tag(&mut self) -> io::Result<Tag> {
Ok(Tag::try_from(self.source.read()?)?)
} }
fn expected(&mut self, k: ExpectedKind) -> error::Error { fn expected(&mut self, k: ExpectedKind) -> error::Error {
match self.demand_next(true) { error::Error::Expected(k)
Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
Err(e) => e.into()
}
} }
#[inline(always)] fn next_nonannotation_tag(&mut self) -> io::Result<Tag> {
fn varint(&mut self) -> io::Result<usize> { self.source.narrow()?;
let mut shift = 0;
let mut acc: usize = 0;
loop { loop {
let v = self.read()?; let tag = self.read_tag()?;
acc |= ((v & 0x7f) as usize) << shift; if tag == Tag::Annotation {
shift += 7; self.source.narrow_to_annotated_value()?;
if v & 0x80 == 0 { return Ok(acc) } } else {
} return Ok(tag);
}
#[inline(always)]
fn peekend(&mut self) -> io::Result<bool> {
if self.peek()? == Tag::End.into() {
self.skip()?;
Ok(true)
} else {
Ok(false)
}
}
#[inline(always)]
fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
loop {
match Tag::try_from(self.peek()?)? {
Tag::Annotation => {
self.skip()?;
self.skip_value()?;
},
other => return Ok(other),
} }
} }
} }
fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> { fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> {
let actual_tag = self.peek_next_nonannotation_tag()?; if self.next_nonannotation_tag()? == expected_tag {
if actual_tag == expected_tag { let bs = self.source.read_to_end()?;
self.skip()?; Ok(self.source.widen(bs)?)
let count = self.varint()?;
Ok(self.readbytes(count)?)
} else { } else {
Err(self.expected(k)) Err(self.expected(k))
} }
@ -139,9 +319,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()> fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()>
{ {
let actual_tag = self.peek_next_nonannotation_tag()?; if self.next_nonannotation_tag()? == expected_tag {
if actual_tag == expected_tag {
self.skip()?;
Ok(()) Ok(())
} else { } else {
Err(self.expected(k)) Err(self.expected(k))
@ -149,246 +327,136 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
} }
#[inline(always)] #[inline(always)]
fn read_signed_integer(&mut self, count: usize) -> io::Result<SignedInteger> { fn next_unsigned<T: FromPrimitive + Debug, F>(&mut self, f: F) -> ReaderResult<T>
if count == 0 {
return Ok(SignedInteger::from(0_i128));
}
if count > 16 {
let bs = self.readbytes(count)?;
if (bs[0] & 0x80) == 0 {
// Positive or zero.
let mut i = 0;
while i < count && bs[i] == 0 { i += 1; }
if count - i <= 16 {
Ok(SignedInteger::from(u128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap())))
} else {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..]))))
}
} else {
// Negative.
let mut i = 0;
while i < count && bs[i] == 0xff { i += 1; }
if count - i <= 16 {
Ok(SignedInteger::from(i128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap())))
} else {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_signed_bytes_be(&bs))))
}
}
} else {
let first_byte = self.read()?;
let prefix_byte = if (first_byte & 0x80) == 0 { 0x00 } else { 0xff };
let mut bs = [prefix_byte; 16];
bs[16 - count] = first_byte;
self.readbytes_into(&mut bs[16 - (count - 1)..])?;
Ok(SignedInteger::from(i128::from_be_bytes(bs)))
}
}
#[inline(always)]
fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
where where
F: FnOnce(u128) -> Option<T> F: FnOnce(u128) -> Option<T>
{ {
let tag = self.peek_next_nonannotation_tag()?; match self.next_nonannotation_tag()? {
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
if v < 0 {
Err(out_of_range(v))
} else {
f(v as u128).ok_or_else(|| out_of_range(v))
}
}
Tag::MediumInteger(count) => {
self.skip()?;
let n = &self.read_signed_integer(count.into())?;
let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i))
}
Tag::SignedInteger => { Tag::SignedInteger => {
self.skip()?; let n = &self.source.read_signed_integer()?;
let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let i = n.try_into().map_err(|_| out_of_range(n))?; let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i)) Ok(self.source.widen(f(i).ok_or_else(|| out_of_range(i))?)?)
} }
_ => Err(self.expected(ExpectedKind::SignedInteger)) _ => Err(self.expected(ExpectedKind::SignedInteger))
} }
} }
#[inline(always)] #[inline(always)]
fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T> fn next_signed<T: FromPrimitive + Debug, F>(&mut self, f: F) -> ReaderResult<T>
where where
F: FnOnce(i128) -> Option<T> F: FnOnce(i128) -> Option<T>
{ {
let tag = self.peek_next_nonannotation_tag()?; match self.next_nonannotation_tag()? {
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
f(v.into()).ok_or_else(|| out_of_range(v))
}
Tag::MediumInteger(count) => {
self.skip()?;
let n = &self.read_signed_integer(count.into())?;
let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i))
}
Tag::SignedInteger => { Tag::SignedInteger => {
self.skip()?; let n = &self.source.read_signed_integer()?;
let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let i = n.try_into().map_err(|_| out_of_range(n))?; let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i)) Ok(self.source.widen(f(i).ok_or_else(|| out_of_range(i))?)?)
} }
_ => Err(self.expected(ExpectedKind::SignedInteger)) _ => Err(self.expected(ExpectedKind::SignedInteger))
} }
} }
fn gather_annotations(&mut self) -> io::Result<Vec<N>> { fn _next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
let mut annotations = vec![self.demand_next(true)?]; &mut self,
while Tag::try_from(self.peek()?)? == Tag::Annotation { read_annotations: bool,
self.skip()?; decode_embedded: &mut Dec,
annotations.push(self.demand_next(true)?); ) -> io::Result<N> {
} loop {
Ok(annotations) return Ok(match self.read_tag()? {
} Tag::False => N::new(false),
Tag::True => N::new(true),
fn skip_annotations(&mut self) -> io::Result<()> { Tag::Float => {
self.skip_value()?; let bs = self.source.read_to_end()?;
while Tag::try_from(self.peek()?)? == Tag::Annotation { match bs.len() {
self.skip()?; 4 => Value::from(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap()))).wrap(),
self.skip_value()?; 8 => Value::from(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap()))).wrap(),
} _ => Err(io_syntax_error("Invalid floating-point width"))?,
Ok(()) }
} }
Tag::SignedInteger => Value::SignedInteger(self.source.read_signed_integer()?).wrap(),
fn next_upto_end(&mut self, read_annotations: bool) -> io::Result<Option<N>> { Tag::String => Value::String(decode_nul_str(self.source.read_to_end()?)?.into_owned()).wrap(),
match self.peekend()? { Tag::ByteString => Value::ByteString(self.source.read_to_end()?.into_owned()).wrap(),
true => Ok(None), Tag::Symbol => Value::Symbol(decodestr(self.source.read_to_end()?)?.into_owned()).wrap(),
false => Ok(Some(self.demand_next(read_annotations)?)), Tag::Record => {
let mut vs = Vec::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
vs.push(v);
}
if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record"))
}
Value::Record(Record(vs)).wrap()
}
Tag::Sequence => {
let mut vs = Vec::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
vs.push(v);
}
Value::Sequence(vs).wrap()
}
Tag::Set => {
let mut s = Set::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
s.insert(v);
}
Value::Set(s).wrap()
}
Tag::Dictionary => {
let mut d = Map::new();
while let Some(k) = self.next(read_annotations, decode_embedded)? {
match self.next(read_annotations, decode_embedded)? {
Some(v) => { d.insert(k, v); }
None => return Err(io_syntax_error("Missing dictionary value")),
}
}
Value::Dictionary(d).wrap()
}
Tag::Embedded => Value::Embedded(
decode_embedded.decode_embedded(self, read_annotations)?).wrap(),
Tag::Annotation => {
if read_annotations {
let underlying: Option<N> = self.next(read_annotations, decode_embedded)?;
match underlying {
Some(v) => {
let mut vs = Vec::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
vs.push(v);
}
let (mut existing_annotations, v) = v.pieces();
existing_annotations.modify(|ws| ws.extend_from_slice(&vs[..]));
N::wrap(existing_annotations, v)
}
None => return Err(io_syntax_error("Missing value in encoded annotation")),
}
} else {
self.source.narrow_to_annotated_value()?;
continue;
}
}
});
} }
} }
} }
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S> {
Reader<'de, N> fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
for PackedReader<'de, 'src, N, Dec, S> &mut self,
{ read_annotations: bool,
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> { decode_embedded: &mut Dec,
match self.peek() { ) -> io::Result<Option<N>> {
Err(e) if is_eof_io_error(&e) => return Ok(None), match self.source.peek()? {
Err(e) => return Err(e), None => Ok(None),
Ok(_) => (), Some(_) => {
self.source.narrow()?;
let v = self._next(read_annotations, decode_embedded)?;
self.source.widen(Some(v))
}
} }
Ok(Some(match Tag::try_from(self.read()?)? {
Tag::False => N::new(false),
Tag::True => N::new(true),
Tag::Float => {
let mut bs = [0; 4];
self.readbytes_into(&mut bs)?;
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
}
Tag::Double => {
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
}
Tag::Annotation => {
if read_annotations {
let mut annotations = self.gather_annotations()?;
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice());
N::wrap(Annotations::new(Some(annotations)), v)
} else {
self.skip_annotations()?;
self.demand_next(read_annotations)?
}
}
Tag::Embedded => {
Value::Embedded(self.decode_embedded.decode_embedded(self.source, read_annotations)?).wrap()
}
Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs
Value::from(v).wrap()
}
Tag::MediumInteger(count) => {
let n = self.read_signed_integer(count.into())?;
Value::SignedInteger(n).wrap()
}
Tag::SignedInteger => {
let count = self.varint()?;
let n = self.read_signed_integer(count)?;
Value::SignedInteger(n).wrap()
}
Tag::String => {
let count = self.varint()?;
Value::String(decodestr(self.readbytes(count)?)?.into_owned()).wrap()
}
Tag::ByteString => {
let count = self.varint()?;
Value::ByteString(self.readbytes(count)?.into_owned()).wrap()
}
Tag::Symbol => {
let count = self.varint()?;
Value::Symbol(decodestr(self.readbytes(count)?)?.into_owned()).wrap()
}
Tag::Record => {
let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations)? { vs.push(v); }
if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record"))
}
Value::Record(Record(vs)).wrap()
}
Tag::Sequence => {
let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations)? { vs.push(v); }
Value::Sequence(vs).wrap()
}
Tag::Set => {
let mut s = Set::new();
while let Some(v) = self.next_upto_end(read_annotations)? { s.insert(v); }
Value::Set(s).wrap()
}
Tag::Dictionary => {
let mut d = Map::new();
while let Some(k) = self.next_upto_end(read_annotations)? {
match self.next_upto_end(read_annotations)? {
Some(v) => { d.insert(k, v); }
None => return Err(io_syntax_error("Missing dictionary value")),
}
}
Value::Dictionary(d).wrap()
}
tag @ Tag::End => {
return Err(io_syntax_error(&format!("Invalid tag: {:?}", tag)));
}
}))
} }
#[inline(always)] #[inline(always)]
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> { fn open_record(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?; self.next_compound(Tag::Record, ExpectedKind::Record)
let mut b = B::Type::default();
self.ensure_more_expected(&mut b, &B::Item::RecordLabel)?;
Ok(b)
}
#[inline(always)]
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
match self.peek_next_nonannotation_tag()? {
Tag::Sequence => {
self.skip()?;
Ok(B::Item::SequenceValue)
}
Tag::Set => {
self.skip()?;
Ok(B::Item::SetValue)
}
_ =>
Err(self.expected(ExpectedKind::SequenceOrSet)),
}
} }
#[inline(always)] #[inline(always)]
@ -413,7 +481,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)] #[inline(always)]
fn close_compound(&mut self, _b: &mut B::Type, _i: &B::Item) -> ReaderResult<bool> { fn close_compound(&mut self, _b: &mut B::Type, _i: &B::Item) -> ReaderResult<bool> {
Ok(self.peekend()?) if self.source.peek()?.is_none() {
Ok(self.source.widen(true)?)
} else {
Ok(false)
}
} }
#[inline(always)] #[inline(always)]
@ -423,95 +495,82 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)] #[inline(always)]
fn close_embedded(&mut self) -> ReaderResult<()> { fn close_embedded(&mut self) -> ReaderResult<()> {
Ok(()) Ok(self.source.widen(())?)
} }
type Mark = S::Mark; type Mark = <PackedReaderSource<'de, 'src, S> as BinarySource<'de>>::Mark;
#[inline(always)] #[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> { fn mark(&mut self) -> io::Result<Self::Mark> {
self.source.mark() BinarySource::mark(&mut self.source)
} }
#[inline(always)] #[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> { fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.source.restore(mark) BinarySource::restore(&mut self.source, mark)
} }
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> { fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
loop { &mut self,
return Ok(match Tag::try_from(self.peek()?)? { read_embedded_annotations: bool,
Tag::Embedded => { decode_embedded: &mut Dec,
self.skip()?; ) -> io::Result<Token<N>> {
Token::Embedded(self.decode_embedded.decode_embedded( match self.source.peek()? {
self.source, None => self.source.widen(Token::End),
read_embedded_annotations)?) Some(_) => {
self.source.narrow()?;
loop {
return match self.peek_tag()? {
Tag::False |
Tag::True |
Tag::Float |
Tag::SignedInteger |
Tag::String |
Tag::ByteString |
Tag::Symbol => {
let v = self._next(false, &mut NoEmbeddedDomainCodec)?;
self.source.widen(Token::Atom(v))
}
Tag::Record => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Record)) }
Tag::Sequence => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Sequence)) }
Tag::Set => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Set)) }
Tag::Dictionary => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Dictionary)) }
Tag::Embedded => {
self.source.skip()?;
let t = Token::Embedded(decode_embedded.decode_embedded(
self, read_embedded_annotations)?);
self.source.widen(t)
}
Tag::Annotation => {
self.source.skip()?;
self.source.narrow_to_annotated_value()?;
continue;
}
}
} }
Tag::False |
Tag::True |
Tag::Float |
Tag::Double |
Tag::SmallInteger(_) |
Tag::MediumInteger(_) |
Tag::SignedInteger |
Tag::String |
Tag::ByteString |
Tag::Symbol =>
Token::Atom(self.demand_next(false)?),
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) }
Tag::Sequence => { self.skip()?; Token::Compound(CompoundClass::Sequence) }
Tag::Set => { self.skip()?; Token::Compound(CompoundClass::Set) }
Tag::Dictionary => { self.skip()?; Token::Compound(CompoundClass::Dictionary) }
Tag::End => { self.skip()?; Token::End }
Tag::Annotation => {
self.skip()?;
self.skip_annotations()?;
continue
}
})
}
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
match Tag::try_from(self.peek()?)? {
Tag::Annotation => {
self.skip()?;
let annotations = self.gather_annotations()?;
Ok((annotations, self.next_token(true)?))
} }
_ => Ok((Vec::new(), self.next_token(true)?)),
} }
} }
#[inline(always)] #[inline(always)]
fn next_boolean(&mut self) -> ReaderResult<bool> { fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_tag()? { match self.next_nonannotation_tag()? {
Tag::False => { self.skip()?; Ok(false) } Tag::False => { Ok(self.source.widen(false)?) }
Tag::True => { self.skip()?; Ok(true) } Tag::True => { Ok(self.source.widen(true)?) }
_ => Err(self.expected(ExpectedKind::Boolean)), _ => Err(self.expected(ExpectedKind::Boolean))?,
} }
} }
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> { fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
let tag = self.peek_next_nonannotation_tag()?; match self.next_nonannotation_tag()? {
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
Ok(SignedInteger::from(v as i32))
}
Tag::MediumInteger(count) => {
self.skip()?;
Ok(self.read_signed_integer(count.into())?)
}
Tag::SignedInteger => { Tag::SignedInteger => {
self.skip()?; let i = self.source.read_signed_integer()?;
let count = self.varint()?; Ok(self.source.widen(i)?)
Ok(self.read_signed_integer(count)?) },
} _ => Err(self.expected(ExpectedKind::SignedInteger))?
_ => Err(self.expected(ExpectedKind::SignedInteger))
} }
} }
@ -528,47 +587,29 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) } fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
fn next_f32(&mut self) -> ReaderResult<f32> { fn next_f32(&mut self) -> ReaderResult<f32> {
match self.peek_next_nonannotation_tag()? { let bs = self.next_atomic(Tag::Float, ExpectedKind::Float)?;
Tag::Float => { match bs.len() {
self.skip()?; 4 => Ok(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap()))),
let mut bs = [0; 4]; 8 => Ok(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap())) as f32),
self.readbytes_into(&mut bs)?; _ => Err(io_syntax_error("Invalid floating-point width"))?,
Ok(f32::from_bits(u32::from_be_bytes(bs)))
},
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32)
},
_ => Err(self.expected(ExpectedKind::Float)),
} }
} }
fn next_f64(&mut self) -> ReaderResult<f64> { fn next_f64(&mut self) -> ReaderResult<f64> {
match self.peek_next_nonannotation_tag()? { let bs = self.next_atomic(Tag::Float, ExpectedKind::Double)?;
Tag::Float => { match bs.len() {
self.skip()?; 4 => Ok(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap())) as f64),
let mut bs = [0; 4]; 8 => Ok(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap()))),
self.readbytes_into(&mut bs)?; _ => Err(io_syntax_error("Invalid floating-point width"))?,
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
},
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)))
},
_ => Err(self.expected(ExpectedKind::Double)),
} }
} }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?) Ok(decode_nul_str(self.next_atomic(Tag::String, ExpectedKind::String)?)?)
} }
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> { fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
self.next_atomic(Tag::ByteString, ExpectedKind::Symbol) self.next_atomic(Tag::ByteString, ExpectedKind::ByteString)
} }
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
@ -585,3 +626,24 @@ fn decodestr(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)), Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)),
} }
} }
fn check_nul(bs: &[u8]) -> io::Result<()> {
if bs.len() < 1 || bs[bs.len() - 1] != 0 {
return Err(io_syntax_error("Missing trailing NUL byte on string"));
}
Ok(())
}
fn decode_nul_str(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
match cow {
Cow::Borrowed(bs) => {
check_nul(bs)?;
decodestr(Cow::Borrowed(&bs[0..bs.len()-1]))
}
Cow::Owned(mut bs) => {
check_nul(&bs)?;
bs.truncate(bs.len() - 1);
decodestr(Cow::Owned(bs))
}
}
}

View File

@ -1,19 +1,22 @@
use num::bigint::BigInt; use num::bigint::BigInt;
use num::cast::ToPrimitive; use num::cast::ToPrimitive;
use std::borrow::Cow;
use std::convert::TryInto; use std::convert::TryInto;
use std::io; use std::io;
use std::ops::DerefMut;
use super::constants::Tag; use super::constants::Tag;
use super::super::DomainEncode; use super::super::DomainEncode;
use super::super::IOValue; use super::super::IOValue;
use super::super::IOValueDomainCodec; use super::super::IOValueDomainCodec;
use super::super::NestedValue; use super::super::NestedValue;
use super::super::boundary as B; use super::super::boundary as B;
use super::super::suspendable::Suspendable; use super::super::iolist::IOList;
use super::super::writer::Writer;
use super::super::writer::{Writer, CompoundWriter, varint}; pub struct PackedWriter<W: io::Write> {
w: W,
pub struct PackedWriter<W: io::Write>(Suspendable<W>); buffer: IOList,
items: Vec<Vec<IOList>>,
}
impl PackedWriter<&mut Vec<u8>> { impl PackedWriter<&mut Vec<u8>> {
#[inline(always)] #[inline(always)]
@ -32,246 +35,86 @@ impl PackedWriter<&mut Vec<u8>> {
} }
} }
pub fn varint(iol: &mut IOList, mut v: usize) {
loop {
if v < 128 {
iol.write((v + 0x80) as u8);
return;
} else {
iol.write((v & 0x7f) as u8);
v >>= 7;
}
}
}
impl<W: io::Write> PackedWriter<W> { impl<W: io::Write> PackedWriter<W> {
#[inline(always)] #[inline(always)]
pub fn new(write: W) -> Self { pub fn new(write: W) -> Self {
PackedWriter(Suspendable::new(write)) PackedWriter {
w: write,
buffer: IOList::new(),
items: Vec::new(),
}
} }
#[inline(always)] #[inline(always)]
pub fn w(&mut self) -> &mut W { pub fn write_byte(&mut self, b: u8) {
self.0.deref_mut() self.buffer.write(b)
} }
#[inline(always)] #[inline(always)]
pub fn write_byte(&mut self, b: u8) -> io::Result<()> { pub fn write_all(&mut self, bs: &[u8]) {
self.w().write_all(&[b]) self.buffer.write_all(Cow::Borrowed(bs))
} }
#[inline(always)] #[inline(always)]
pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> { pub fn write_integer(&mut self, bs: &[u8]) -> io::Result<()> {
let count: u8 = bs.len().try_into().unwrap(); self.write_atom(Tag::SignedInteger, bs)
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) } }
self.write_byte(Tag::MediumInteger(count).into())?;
self.w().write_all(bs) #[inline(always)]
pub fn write_tag(&mut self, tag: Tag) {
self.write_byte(tag.into())
} }
#[inline(always)] #[inline(always)]
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> io::Result<()> { pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> io::Result<()> {
self.write_byte(tag.into())?; self.write_tag(tag);
varint(&mut self.w(), bs.len().try_into().unwrap())?; self.write_all(bs);
self.w().write_all(bs) self.finish_item_if_toplevel()
} }
#[inline(always)] pub fn finish_item(&mut self) -> io::Result<()> {
pub fn suspend(&mut self) -> Self { let buffer = std::mem::replace(&mut self.buffer, IOList::new());
PackedWriter(self.0.suspend()) match self.items.last_mut() {
} Some(iols) => Ok(iols.push(buffer)),
None => buffer.write_to(&mut self.w),
#[inline(always)]
pub fn resume(&mut self, other: Self) {
self.0.resume(other.0)
}
}
pub struct BinaryOrderWriter(Vec<Vec<u8>>);
impl BinaryOrderWriter {
#[inline(always)]
fn new() -> Self {
BinaryOrderWriter(vec![vec![]])
}
#[inline(always)]
fn pop(&mut self) -> PackedWriter<Vec<u8>> {
PackedWriter::new(self.0.pop().unwrap())
}
#[inline(always)]
fn push(&mut self, w: PackedWriter<Vec<u8>>) {
self.0.push(w.0.take())
}
#[inline(always)]
fn items(&self) -> &Vec<Vec<u8>> {
&self.0
}
#[inline(always)]
fn items_mut(&mut self) -> &mut Vec<Vec<u8>> {
&mut self.0
}
#[inline(always)]
fn buffer(&mut self) -> &mut Vec<u8> {
self.0.last_mut().unwrap()
}
#[inline(always)]
fn finish<W: WriteWriter>(mut self, w: &mut W) -> io::Result<()> {
if !self.buffer().is_empty() { panic!("Missing final boundary()"); }
self.items_mut().pop();
self.items_mut().sort();
for bs in self.items() {
w.write_raw_bytes(&bs)?;
} }
w.write_tag(Tag::End)?;
Ok(())
} }
}
pub trait WriteWriter: Writer { pub fn finish_item_if_toplevel(&mut self) -> io::Result<()> {
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()>; if self.items.is_empty() {
self.finish_item()?;
#[inline(always)]
fn write_tag(&mut self, tag: Tag) -> io::Result<()> {
self.write_raw_bytes(&[tag.into()])
}
}
impl<W: io::Write> WriteWriter for PackedWriter<W> {
#[inline(always)]
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
self.w().write_all(v)
}
}
impl WriteWriter for BinaryOrderWriter {
#[inline(always)]
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
use io::Write;
self.buffer().write_all(v)
}
}
impl<W: io::Write> CompoundWriter for PackedWriter<W> {
#[inline(always)]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
if let Some(B::Item::Annotation) = b.opening {
self.write_tag(Tag::Annotation)?;
} }
Ok(()) Ok(())
} }
}
impl CompoundWriter for BinaryOrderWriter { pub fn start_seq(&mut self) -> io::Result<()> {
#[inline(always)] self.items.push(Vec::new());
fn boundary(&mut self, b: &B::Type) -> io::Result<()> { Ok(())
match b.closing { }
Some(B::Item::DictionaryValue) |
Some(B::Item::RecordField) | pub fn finish_seq(&mut self, tag: Tag, sort: bool) -> io::Result<()> {
Some(B::Item::SequenceValue) | let mut items = self.items.pop().unwrap();
Some(B::Item::SetValue) => if sort {
self.items_mut().push(vec![]), items.sort();
_ =>
()
} }
Ok(()) self.write_tag(tag);
} for mut i in items {
} varint(&mut self.buffer, i.len());
self.buffer.append(i);
macro_rules! binary_order_writer_method { }
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) => self.finish_item_if_toplevel()
(#[inline(always)] fn $n (&mut self, $($argname : $argty),*) -> $retty {
(&mut PackedWriter::new(self.buffer())).$n($($argname),*)
});
}
impl Writer for BinaryOrderWriter {
type AnnWriter = PackedWriter<Vec<u8>>;
type RecWriter = PackedWriter<Vec<u8>>;
type SeqWriter = PackedWriter<Vec<u8>>;
type SetWriter = BinaryOrderWriter;
type DictWriter = BinaryOrderWriter;
type EmbeddedWriter = PackedWriter<Vec<u8>>;
#[inline(always)]
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.pop())
}
#[inline(always)]
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.push(ann);
Ok(())
}
binary_order_writer_method!(mut write_bool(v: bool) -> io::Result<()>);
binary_order_writer_method!(mut write_f32(v: f32) -> io::Result<()>);
binary_order_writer_method!(mut write_f64(v: f64) -> io::Result<()>);
binary_order_writer_method!(mut write_i8(v: i8) -> io::Result<()>);
binary_order_writer_method!(mut write_u8(v: u8) -> io::Result<()>);
binary_order_writer_method!(mut write_i16(v: i16) -> io::Result<()>);
binary_order_writer_method!(mut write_u16(v: u16) -> io::Result<()>);
binary_order_writer_method!(mut write_i32(v: i32) -> io::Result<()>);
binary_order_writer_method!(mut write_u32(v: u32) -> io::Result<()>);
binary_order_writer_method!(mut write_i64(v: i64) -> io::Result<()>);
binary_order_writer_method!(mut write_u64(v: u64) -> io::Result<()>);
binary_order_writer_method!(mut write_i128(v: i128) -> io::Result<()>);
binary_order_writer_method!(mut write_u128(v: u128) -> io::Result<()>);
binary_order_writer_method!(mut write_int(v: &BigInt) -> io::Result<()>);
binary_order_writer_method!(mut write_string(v: &str) -> io::Result<()>);
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> io::Result<()>);
binary_order_writer_method!(mut write_symbol(v: &str) -> io::Result<()>);
#[inline(always)]
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
self.write_tag(Tag::Record)?;
Ok(self.pop())
}
#[inline(always)]
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.push(rec);
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.pop())
}
#[inline(always)]
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.push(seq);
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
#[inline(always)]
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
set.finish(self)
}
#[inline(always)]
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
#[inline(always)]
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
dict.finish(self)
}
#[inline(always)]
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
self.write_tag(Tag::Embedded)?;
Ok(self.pop())
}
#[inline(always)]
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
self.push(ptr);
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
Ok(())
} }
} }
@ -284,162 +127,171 @@ macro_rules! fits_in_bytes {
impl<W: io::Write> Writer for PackedWriter<W> impl<W: io::Write> Writer for PackedWriter<W>
{ {
type AnnWriter = Self;
type RecWriter = Self;
type SeqWriter = Self;
type SetWriter = BinaryOrderWriter;
type DictWriter = BinaryOrderWriter;
type EmbeddedWriter = Self;
#[inline(always)] #[inline(always)]
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> { fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
Ok(self.suspend()) match (b.closing.as_ref(), b.opening.as_ref()) {
(Some(_), _) =>
self.finish_item(),
(None, _) =>
Ok(()),
}
} }
#[inline(always)] #[inline(always)]
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> { fn start_annotations(&mut self) -> io::Result<()> {
self.resume(ann); self.start_seq()
Ok(()) }
#[inline(always)]
fn end_annotations(&mut self) -> io::Result<()> {
self.items.last_mut().unwrap().rotate_right(1);
self.finish_seq(Tag::Annotation, false)
} }
#[inline(always)] #[inline(always)]
fn write_bool(&mut self, v: bool) -> io::Result<()> { fn write_bool(&mut self, v: bool) -> io::Result<()> {
self.write_tag(if v { Tag::True } else { Tag::False }) self.write_tag(if v { Tag::True } else { Tag::False });
self.finish_item_if_toplevel()
} }
#[inline(always)] #[inline(always)]
fn write_f32(&mut self, v: f32) -> io::Result<()> { fn write_f32(&mut self, v: f32) -> io::Result<()> {
self.write_tag(Tag::Float)?; self.write_tag(Tag::Float);
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v))) self.write_all(&u32::to_be_bytes(f32::to_bits(v)));
self.finish_item_if_toplevel()
} }
#[inline(always)] #[inline(always)]
fn write_f64(&mut self, v: f64) -> io::Result<()> { fn write_f64(&mut self, v: f64) -> io::Result<()> {
self.write_tag(Tag::Double)?; self.write_tag(Tag::Float);
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v))) self.write_all(&u64::to_be_bytes(f64::to_bits(v)));
self.finish_item_if_toplevel()
} }
#[inline(always)] #[inline(always)]
fn write_i8(&mut self, v: i8) -> io::Result<()> { fn write_i8(&mut self, v: i8) -> io::Result<()> {
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) } if v == 0 {
self.write_medium_integer(&[v as u8]) self.write_integer(&[])
} else {
self.write_integer(&[v as u8])
}
} }
#[inline(always)] #[inline(always)]
fn write_u8(&mut self, v: u8) -> io::Result<()> { fn write_u8(&mut self, v: u8) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) } if let Ok(w) = v.try_into() { return self.write_i8(w) }
self.write_medium_integer(&[0, v]) self.write_integer(&[0, v])
} }
#[inline(always)] #[inline(always)]
fn write_i16(&mut self, v: i16) -> io::Result<()> { fn write_i16(&mut self, v: i16) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) } if let Ok(w) = v.try_into() { return self.write_i8(w) }
self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8]) self.write_integer(&[(v >> 8) as u8, (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_u16(&mut self, v: u16) -> io::Result<()> { fn write_u16(&mut self, v: u16) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) } if let Ok(w) = v.try_into() { return self.write_i16(w) }
self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8]) self.write_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_i32(&mut self, v: i32) -> io::Result<()> { fn write_i32(&mut self, v: i32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) } if let Ok(w) = v.try_into() { return self.write_i16(w) }
if fits_in_bytes!(v, 3) { if fits_in_bytes!(v, 3) {
return self.write_medium_integer(&[(v >> 16) as u8, return self.write_integer(&[(v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
self.write_medium_integer(&[(v >> 24) as u8, self.write_integer(&[(v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]) (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_u32(&mut self, v: u32) -> io::Result<()> { fn write_u32(&mut self, v: u32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) } if let Ok(w) = v.try_into() { return self.write_i32(w) }
self.write_medium_integer(&[0, self.write_integer(&[0,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]) (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_i64(&mut self, v: i64) -> io::Result<()> { fn write_i64(&mut self, v: i64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) } if let Ok(w) = v.try_into() { return self.write_i32(w) }
if fits_in_bytes!(v, 5) { if fits_in_bytes!(v, 5) {
return self.write_medium_integer(&[(v >> 32) as u8, return self.write_integer(&[(v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
if fits_in_bytes!(v, 6) { if fits_in_bytes!(v, 6) {
return self.write_medium_integer(&[(v >> 40) as u8, return self.write_integer(&[(v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
if fits_in_bytes!(v, 7) { if fits_in_bytes!(v, 7) {
return self.write_medium_integer(&[(v >> 48) as u8, return self.write_integer(&[(v >> 48) as u8,
(v >> 40) as u8, (v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
self.write_medium_integer(&[(v >> 56) as u8, self.write_integer(&[(v >> 56) as u8,
(v >> 48) as u8, (v >> 48) as u8,
(v >> 40) as u8, (v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]) (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_u64(&mut self, v: u64) -> io::Result<()> { fn write_u64(&mut self, v: u64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) } if let Ok(w) = v.try_into() { return self.write_i64(w) }
self.write_medium_integer(&[0, self.write_integer(&[0,
(v >> 56) as u8, (v >> 56) as u8,
(v >> 48) as u8, (v >> 48) as u8,
(v >> 40) as u8, (v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]) (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_i128(&mut self, v: i128) -> io::Result<()> { fn write_i128(&mut self, v: i128) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) } if let Ok(w) = v.try_into() { return self.write_i64(w) }
let bs: [u8; 16] = v.to_be_bytes(); let bs: [u8; 16] = v.to_be_bytes();
if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); } if fits_in_bytes!(v, 9) { return self.write_integer(&bs[7..]); }
if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); } if fits_in_bytes!(v, 10) { return self.write_integer(&bs[6..]); }
if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); } if fits_in_bytes!(v, 11) { return self.write_integer(&bs[5..]); }
if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); } if fits_in_bytes!(v, 12) { return self.write_integer(&bs[4..]); }
if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); } if fits_in_bytes!(v, 13) { return self.write_integer(&bs[3..]); }
if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); } if fits_in_bytes!(v, 14) { return self.write_integer(&bs[2..]); }
if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); } if fits_in_bytes!(v, 15) { return self.write_integer(&bs[1..]); }
self.write_medium_integer(&bs) self.write_integer(&bs)
} }
#[inline(always)] #[inline(always)]
fn write_u128(&mut self, v: u128) -> io::Result<()> { fn write_u128(&mut self, v: u128) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i128(w) } if let Ok(w) = v.try_into() { return self.write_i128(w) }
let bs: [u8; 16] = v.to_be_bytes(); let bs: [u8; 16] = v.to_be_bytes();
self.write_tag(Tag::SignedInteger)?; self.write_tag(Tag::SignedInteger);
varint(&mut self.w(), 17)?; self.write_byte(0);
self.write_byte(0)?; self.write_all(&bs);
self.write_raw_bytes(&bs) Ok(())
} }
#[inline(always)] #[inline(always)]
@ -457,7 +309,10 @@ impl<W: io::Write> Writer for PackedWriter<W>
#[inline(always)] #[inline(always)]
fn write_string(&mut self, v: &str) -> io::Result<()> { fn write_string(&mut self, v: &str) -> io::Result<()> {
self.write_atom(Tag::String, v.as_bytes()) self.write_tag(Tag::String);
self.write_all(v.as_bytes());
self.write_byte(0);
self.finish_item_if_toplevel()
} }
#[inline(always)] #[inline(always)]
@ -471,65 +326,84 @@ impl<W: io::Write> Writer for PackedWriter<W>
} }
#[inline(always)] #[inline(always)]
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> { fn start_record(&mut self) -> io::Result<()> {
self.write_tag(Tag::Record)?; self.start_seq()
Ok(self.suspend())
} }
#[inline(always)] #[inline(always)]
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> { fn end_record(&mut self) -> io::Result<()> {
self.resume(rec); self.finish_seq(Tag::Record, false)
self.write_tag(Tag::End)
} }
#[inline(always)] #[inline(always)]
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> { fn start_sequence(&mut self) -> io::Result<()> {
self.write_tag(Tag::Sequence)?; self.start_seq()
Ok(self.suspend())
} }
#[inline(always)] #[inline(always)]
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> { fn end_sequence(&mut self) -> io::Result<()> {
self.resume(seq); self.finish_seq(Tag::Sequence, false)
self.write_tag(Tag::End)
} }
#[inline(always)] #[inline(always)]
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> { fn start_set(&mut self) -> io::Result<()> {
self.write_tag(Tag::Set)?; self.start_seq()
Ok(BinaryOrderWriter::new())
} }
#[inline(always)] #[inline(always)]
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> { fn end_set(&mut self) -> io::Result<()> {
set.finish(self) self.finish_seq(Tag::Set, true)
} }
#[inline(always)] #[inline(always)]
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> { fn start_dictionary(&mut self) -> io::Result<()> {
self.write_tag(Tag::Dictionary)?; self.start_seq()
Ok(BinaryOrderWriter::new())
} }
#[inline(always)] #[inline(always)]
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> { fn end_dictionary(&mut self) -> io::Result<()> {
dict.finish(self) let mut items_iter = self.items.pop().unwrap().into_iter();
let mut chunks = vec![];
while let Some(ki) = items_iter.next() {
match items_iter.next() {
Some(vi) => chunks.push((ki, vi)),
None => panic!("Missing dictionary value during serialization"),
}
}
chunks.sort();
self.write_tag(Tag::Dictionary);
for (mut ki, mut vi) in chunks {
varint(&mut self.buffer, ki.len());
self.buffer.append(ki);
varint(&mut self.buffer, vi.len());
self.buffer.append(vi);
}
Ok(())
} }
#[inline(always)] #[inline(always)]
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> { fn start_embedded(&mut self) -> io::Result<()> {
self.write_tag(Tag::Embedded)?; self.write_tag(Tag::Embedded);
Ok(self.suspend()) Ok(())
} }
#[inline(always)] #[inline(always)]
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> io::Result<()> { fn end_embedded(&mut self) -> io::Result<()> {
self.resume(ann);
Ok(()) Ok(())
} }
#[inline(always)] #[inline(always)]
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
self.0.flush() if self.buffer.len() != 0 { panic!("Attempt to flush with unfinished item in buffer"); }
self.w.flush()
}
fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> {
self.inner_write(enc, v)?;
self.finish_item_if_toplevel()
} }
} }

View File

@ -1,4 +1,4 @@
use crate::error::{self, ExpectedKind, Received, io_eof}; use crate::error::{self, ExpectedKind, io_eof};
use std::borrow::Cow; use std::borrow::Cow;
use std::io; use std::io;
@ -6,18 +6,18 @@ use std::marker::PhantomData;
use super::CompoundClass; use super::CompoundClass;
use super::DomainDecode; use super::DomainDecode;
use super::DomainParse;
use super::Double; use super::Double;
use super::DummyValue;
use super::Float; use super::Float;
use super::IOValue; use super::IOValue;
use super::IOValueDomainCodec; use super::IOValueDomainCodec;
use super::NestedValue; use super::NestedValue;
use super::ViaCodec;
use super::boundary as B; use super::boundary as B;
use super::signed_integer::SignedInteger; use super::signed_integer::SignedInteger;
pub type ReaderResult<T> = std::result::Result<T, error::Error>; pub type ReaderResult<T> = std::result::Result<T, error::Error>;
#[derive(Debug)]
pub enum Token<N: NestedValue> { pub enum Token<N: NestedValue> {
Embedded(N::Embedded), Embedded(N::Embedded),
Atom(N), Atom(N),
@ -25,16 +25,21 @@ pub enum Token<N: NestedValue> {
End, End,
} }
pub trait Reader<'de, N: NestedValue> { pub trait Reader<'de> {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>>; fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type>; &mut self,
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item>; read_annotations: bool,
fn open_sequence(&mut self) -> ReaderResult<()>; decode_embedded: &mut Dec,
fn open_set(&mut self) -> ReaderResult<()>; ) -> io::Result<Option<N>>;
fn open_dictionary(&mut self) -> ReaderResult<()>;
fn open_record(&mut self) -> ReaderResult<()>; // followed by label, then fields
fn open_sequence(&mut self) -> ReaderResult<()>; // followed by items
fn open_set(&mut self) -> ReaderResult<()>; // followed by items
fn open_dictionary(&mut self) -> ReaderResult<()>; // followed by key/value pairs
fn boundary(&mut self, b: &B::Type) -> ReaderResult<()>; fn boundary(&mut self, b: &B::Type) -> ReaderResult<()>;
// close_compound implies a b.shift(...) and a self.boundary(b). // Answers true for closed, false for more.
// Implies a b.shift of None if closed or of Some(i) if not closed, plus a .boundary.
fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool>; fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool>;
fn open_embedded(&mut self) -> ReaderResult<()>; fn open_embedded(&mut self) -> ReaderResult<()>;
@ -44,103 +49,107 @@ pub trait Reader<'de, N: NestedValue> {
fn mark(&mut self) -> io::Result<Self::Mark>; fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>; fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>>; fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)>; &mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>>;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
fn skip_value(&mut self) -> io::Result<()> { fn skip_value(&mut self) -> io::Result<()> {
// TODO efficient skipping in specific impls of this trait // TODO efficient skipping in specific impls of this trait
let _ = self.demand_next(false)?; let _: DummyValue<IOValue> = self.demand_next(false, &mut IOValueDomainCodec)?;
Ok(()) Ok(())
} }
fn demand_next(&mut self, read_annotations: bool) -> io::Result<N> { fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
self.next(read_annotations)?.ok_or_else(io_eof) self.demand_next(read_annotations, &mut IOValueDomainCodec)
}
fn demand_next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
self.next(read_annotations, decode_embedded)?.ok_or_else(io_eof)
} }
fn next_boolean(&mut self) -> ReaderResult<bool> { fn next_boolean(&mut self) -> ReaderResult<bool> {
self.demand_next(false)?.value().to_boolean() self.next_iovalue(false)?.value().to_boolean()
} }
fn next_float(&mut self) -> ReaderResult<Float> { fn next_float(&mut self) -> ReaderResult<Float> {
Ok(self.demand_next(false)?.value().to_float()?.to_owned()) Ok(self.next_iovalue(false)?.value().to_float()?.to_owned())
} }
fn next_double(&mut self) -> ReaderResult<Double> { fn next_double(&mut self) -> ReaderResult<Double> {
Ok(self.demand_next(false)?.value().to_double()?.to_owned()) Ok(self.next_iovalue(false)?.value().to_double()?.to_owned())
} }
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> { fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
Ok(self.demand_next(false)?.value().to_signedinteger()?.to_owned()) Ok(self.next_iovalue(false)?.value().to_signedinteger()?.to_owned())
} }
fn next_i8(&mut self) -> ReaderResult<i8> { self.demand_next(false)?.value().to_i8() } fn next_i8(&mut self) -> ReaderResult<i8> { self.next_iovalue(false)?.value().to_i8() }
fn next_u8(&mut self) -> ReaderResult<u8> { self.demand_next(false)?.value().to_u8() } fn next_u8(&mut self) -> ReaderResult<u8> { self.next_iovalue(false)?.value().to_u8() }
fn next_i16(&mut self) -> ReaderResult<i16> { self.demand_next(false)?.value().to_i16() } fn next_i16(&mut self) -> ReaderResult<i16> { self.next_iovalue(false)?.value().to_i16() }
fn next_u16(&mut self) -> ReaderResult<u16> { self.demand_next(false)?.value().to_u16() } fn next_u16(&mut self) -> ReaderResult<u16> { self.next_iovalue(false)?.value().to_u16() }
fn next_i32(&mut self) -> ReaderResult<i32> { self.demand_next(false)?.value().to_i32() } fn next_i32(&mut self) -> ReaderResult<i32> { self.next_iovalue(false)?.value().to_i32() }
fn next_u32(&mut self) -> ReaderResult<u32> { self.demand_next(false)?.value().to_u32() } fn next_u32(&mut self) -> ReaderResult<u32> { self.next_iovalue(false)?.value().to_u32() }
fn next_i64(&mut self) -> ReaderResult<i64> { self.demand_next(false)?.value().to_i64() } fn next_i64(&mut self) -> ReaderResult<i64> { self.next_iovalue(false)?.value().to_i64() }
fn next_u64(&mut self) -> ReaderResult<u64> { self.demand_next(false)?.value().to_u64() } fn next_u64(&mut self) -> ReaderResult<u64> { self.next_iovalue(false)?.value().to_u64() }
fn next_i128(&mut self) -> ReaderResult<i128> { self.demand_next(false)?.value().to_i128() } fn next_i128(&mut self) -> ReaderResult<i128> { self.next_iovalue(false)?.value().to_i128() }
fn next_u128(&mut self) -> ReaderResult<u128> { self.demand_next(false)?.value().to_u128() } fn next_u128(&mut self) -> ReaderResult<u128> { self.next_iovalue(false)?.value().to_u128() }
fn next_f32(&mut self) -> ReaderResult<f32> { self.demand_next(false)?.value().to_f32() } fn next_f32(&mut self) -> ReaderResult<f32> { self.next_iovalue(false)?.value().to_f32() }
fn next_f64(&mut self) -> ReaderResult<f64> { self.demand_next(false)?.value().to_f64() } fn next_f64(&mut self) -> ReaderResult<f64> { self.next_iovalue(false)?.value().to_f64() }
fn next_char(&mut self) -> ReaderResult<char> { self.demand_next(false)?.value().to_char() } fn next_char(&mut self) -> ReaderResult<char> { self.next_iovalue(false)?.value().to_char() }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_string()?.to_owned())) Ok(Cow::Owned(self.next_iovalue(false)?.value().to_string()?.to_owned()))
} }
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> { fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_bytestring()?.to_owned())) Ok(Cow::Owned(self.next_iovalue(false)?.value().to_bytestring()?.to_owned()))
} }
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned())) Ok(Cow::Owned(self.next_iovalue(false)?.value().to_symbol()?.to_owned()))
} }
fn open_option(&mut self) -> ReaderResult<Option<B::Type>> fn open_simple_record(&mut self, name: &str) -> ReaderResult<()>
{ {
let b = self.open_record(None)?; let b = self.open_record()?;
let label: &str = &self.next_symbol()?;
match label {
"None" => {
self.ensure_complete(b, &B::Item::RecordField)?;
Ok(None)
}
"Some" =>
Ok(Some(b)),
_ =>
Err(error::Error::Expected(ExpectedKind::Option,
Received::ReceivedRecordWithLabel(label.to_owned()))),
}
}
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<B::Type>
{
let b = self.open_record(arity)?;
let label: &str = &self.next_symbol()?; let label: &str = &self.next_symbol()?;
if label == name { if label == name {
Ok(b) Ok(b)
} else { } else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity), Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned())))
Received::ReceivedRecordWithLabel(label.to_owned())))
} }
} }
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, N, Self> fn configured<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
self,
read_annotations: bool,
decode_embedded: Dec,
) -> ConfiguredReader<'de, N, Dec, Self>
where where
Self: std::marker::Sized Self: std::marker::Sized
{ {
ConfiguredReader { ConfiguredReader {
reader: self, reader: self,
read_annotations, read_annotations,
decode_embedded,
phantom: PhantomData, phantom: PhantomData,
} }
} }
fn iovalues(self) -> ConfiguredReader<'de, IOValue, IOValueDomainCodec, Self>
where Self: Sized
{
self.configured(true, IOValueDomainCodec)
}
fn ensure_more_expected(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<()> { fn ensure_more_expected(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<()> {
if !self.close_compound(b, i)? { if !self.close_compound(b, i)? {
Ok(()) Ok(())
@ -158,17 +167,17 @@ pub trait Reader<'de, N: NestedValue> {
} }
} }
impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R { impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> { fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
(*self).next(read_annotations) &mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
(*self).next(read_annotations, decode_embedded)
} }
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> { fn open_record(&mut self) -> ReaderResult<()> {
(*self).open_record(arity) (*self).open_record()
}
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
(*self).open_sequence_or_set()
} }
fn open_sequence(&mut self) -> ReaderResult<()> { fn open_sequence(&mut self) -> ReaderResult<()> {
@ -209,210 +218,50 @@ impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R {
(*self).restore(mark) (*self).restore(mark)
} }
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> { fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
(*self).next_token(read_embedded_annotations)
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
(*self).next_annotations_and_token()
}
}
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn skip(&mut self) -> io::Result<()>;
fn peek(&mut self) -> io::Result<u8>;
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()>;
fn packed<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self, &mut self,
decode_embedded: Dec, read_embedded_annotations: bool,
) -> super::PackedReader<'de, '_, N, Dec, Self> { decode_embedded: &mut Dec,
super::PackedReader::new(self, decode_embedded) ) -> io::Result<Token<N>> {
} (*self).next_token(read_embedded_annotations, decode_embedded)
fn packed_iovalues(&mut self) ->
super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self>
{
self.packed(IOValueDomainCodec)
}
fn text<N: NestedValue, Dec: DomainParse<N::Embedded>>(
&mut self,
decode_embedded: Dec,
) -> super::TextReader<'de, '_, N::Embedded, Dec, Self> {
super::TextReader::new(self, decode_embedded)
}
fn text_iovalues(&mut self) ->
super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self>
{
self.text::<IOValue, _>(ViaCodec::new(IOValueDomainCodec))
} }
} }
pub struct IOBinarySource<R: io::Read + io::Seek> { pub struct ConfiguredReader<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
pub read: R, {
pub buf: Option<u8>,
}
impl<R: io::Read + io::Seek> IOBinarySource<R> {
#[inline(always)]
pub fn new(read: R) -> Self {
IOBinarySource { read, buf: None }
}
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
self.buf = None;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
self.buf = None;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
match self.buf {
Some(b) => Ok(b),
None => {
let b = &mut [0];
match self.read.read(b)? {
0 => Err(io_eof()),
1 => {
self.buf = Some(b[0]);
Ok(b[0])
}
_ => unreachable!(),
}
}
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); }
let mut bs = vec![0; count];
self.read.read_exact(&mut bs)?;
Ok(Cow::Owned(bs))
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
self.read.read_exact(bs)
}
}
pub struct BytesBinarySource<'de> {
pub bytes: &'de [u8],
pub index: usize,
}
impl<'de> BytesBinarySource<'de> {
#[inline(always)]
pub fn new(bytes: &'de [u8]) -> Self {
BytesBinarySource { bytes, index: 0 }
}
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = usize;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index >= self.bytes.len() { unreachable!(); }
self.index += 1;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
if self.index >= self.bytes.len() {
Err(io_eof())
} else {
Ok(self.bytes[self.index])
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[self.index..self.index+count];
self.index += count;
Ok(Cow::Borrowed(bs))
}
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
let count = bs.len();
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
bs.copy_from_slice(&self.bytes[self.index..self.index+count]);
self.index += count;
Ok(())
}
}
}
pub struct ConfiguredReader<'de, N: NestedValue, R: Reader<'de, N>> {
pub reader: R, pub reader: R,
pub read_annotations: bool, pub read_annotations: bool,
pub decode_embedded: Dec,
phantom: PhantomData<&'de N>, phantom: PhantomData<&'de N>,
} }
impl<'de, N: NestedValue, R: Reader<'de, N>> ConfiguredReader<'de, N, R> { impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
pub fn new(reader: R) -> Self { ConfiguredReader<'de, N, Dec, R>
reader.configured(true) {
pub fn new(reader: R, decode_embedded: Dec) -> Self {
reader.configured(true, decode_embedded)
} }
pub fn set_read_annotations(&mut self, read_annotations: bool) { pub fn set_read_annotations(&mut self, read_annotations: bool) {
self.read_annotations = read_annotations self.read_annotations = read_annotations;
} }
pub fn demand_next(&mut self) -> io::Result<N> { pub fn demand_next(&mut self) -> io::Result<N> {
self.reader.demand_next(self.read_annotations) self.reader.demand_next(self.read_annotations, &mut self.decode_embedded)
}
pub fn next_token(&mut self) -> io::Result<Token<N>> {
self.reader.next_token(self.read_annotations, &mut self.decode_embedded)
} }
} }
impl<'de, N: NestedValue, R: Reader<'de, N>> std::iter::Iterator for ConfiguredReader<'de, N, R> { impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
std::iter::Iterator
for ConfiguredReader<'de, N, Dec, R>
{
type Item = io::Result<N>; type Item = io::Result<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, &mut self.decode_embedded) {
Err(e) => Some(Err(e)), Err(e) => Some(Err(e)),
Ok(None) => None, Ok(None) => None,
Ok(Some(v)) => Some(Ok(v)), Ok(Some(v)) => Some(Ok(v)),

View File

@ -17,7 +17,7 @@ pub use std::collections::BTreeSet as Set;
pub use std::collections::BTreeMap as Map; pub use std::collections::BTreeMap as Map;
use super::signed_integer::SignedInteger; use super::signed_integer::SignedInteger;
use crate::error::{Error, ExpectedKind, Received}; use crate::error::{Error, ExpectedKind};
pub trait Domain: Sized + Debug + Eq + Hash + Ord {} pub trait Domain: Sized + Debug + Eq + Hash + Ord {}
pub trait Embeddable: Domain + Clone {} pub trait Embeddable: Domain + Clone {}
@ -398,7 +398,7 @@ impl<N: NestedValue> Value<N> {
} }
fn expected(&self, k: ExpectedKind) -> Error { fn expected(&self, k: ExpectedKind) -> Error {
Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap()))) Error::Expected(k)
} }
#[inline(always)] #[inline(always)]
@ -877,7 +877,7 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> { pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> {
self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record(arity))) self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record))
} }
#[inline(always)] #[inline(always)]
@ -917,7 +917,7 @@ impl<N: NestedValue> Value<N> {
Result<&[N], Error> Result<&[N], Error>
{ {
self.as_simple_record(label, arity) self.as_simple_record(label, arity)
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity))) .ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned())))
} }
#[inline(always)] #[inline(always)]
@ -1515,22 +1515,22 @@ impl<D: Embeddable> NestedValue for DummyValue<D> {
#[inline(always)] #[inline(always)]
fn annotations(&self) -> &Annotations<Self> { fn annotations(&self) -> &Annotations<Self> {
&self.0.0 &(self.0).0
} }
#[inline(always)] #[inline(always)]
fn value(&self) -> &Value<Self> { fn value(&self) -> &Value<Self> {
&self.0.1 &(self.0).1
} }
#[inline(always)] #[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) { fn pieces(self) -> (Annotations<Self>, Value<Self>) {
(self.0.0, self.0.1) ((self.0).0, (self.0).1)
} }
#[inline(always)] #[inline(always)]
fn value_owned(self) -> Value<Self> { fn value_owned(self) -> Value<Self> {
self.0.1 (self.0).1
} }
} }

View File

@ -0,0 +1,193 @@
use crate::error::io_eof;
use std::borrow::Cow;
use std::io;
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn skip(&mut self) -> io::Result<()>;
fn peek(&mut self) -> io::Result<Option<u8>>;
fn discard(&mut self, count: u64) -> io::Result<()>;
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()>;
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>>;
//---------------------------------------------------------------------------
fn packed(&mut self) -> super::PackedReader<'de, '_, Self> {
super::PackedReader::new(self)
}
fn text(&mut self) -> super::TextReader<'de, '_, Self> {
super::TextReader::new(self)
}
}
pub struct IOBinarySource<R: io::Read + io::Seek> {
pub read: R,
pub buf: Option<u8>,
}
impl<R: io::Read + io::Seek> IOBinarySource<R> {
#[inline(always)]
pub fn new(read: R) -> Self {
IOBinarySource { read, buf: None }
}
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
self.buf = None;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
self.buf = None;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<Option<u8>> {
match self.buf {
Some(b) => Ok(Some(b)),
None => {
let b = &mut [0];
match self.read.read(b)? {
0 => Ok(None),
1 => {
self.buf = Some(b[0]);
Ok(Some(b[0]))
}
_ => unreachable!(),
}
}
}
}
fn discard(&mut self, mut count: u64) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
while count > i64::MAX as u64 {
self.read.seek(io::SeekFrom::Current(i64::MAX))?;
count -= i64::MAX as u64;
}
self.read.seek(io::SeekFrom::Current(count as i64))?;
Ok(())
}
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
let mut bs = vec![0; count as usize];
self.readbytes_into(&mut bs)?;
Ok(Cow::Owned(bs))
}
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
self.read.read_exact(bs)
}
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); }
let mut bs = Vec::new();
self.read.read_to_end(&mut bs)?;
Ok(Cow::Owned(bs))
}
}
pub struct BytesBinarySource<'de> {
pub bytes: &'de [u8],
pub index: u64,
}
impl<'de> BytesBinarySource<'de> {
#[inline(always)]
pub fn new(bytes: &'de [u8]) -> Self {
BytesBinarySource { bytes, index: 0 }
}
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index as usize >= self.bytes.len() { unreachable!(); }
self.index += 1;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<Option<u8>> {
if self.index as usize >= self.bytes.len() {
Ok(None)
} else {
Ok(Some(self.bytes[self.index as usize]))
}
}
#[inline(always)]
fn discard(&mut self, count: u64) -> io::Result<()> {
if (self.index + count) as usize > self.bytes.len() {
Err(io_eof())
} else {
self.index += count;
Ok(())
}
}
#[inline(always)]
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
let base = self.index as usize;
let limit = base + count as usize;
if limit > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[base..limit];
self.index += count;
Ok(Cow::Borrowed(bs))
}
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
let base = self.index as usize;
let count = bs.len();
let limit = base + count;
if limit > self.bytes.len() {
Err(io_eof())
} else {
bs.copy_from_slice(&self.bytes[base..limit]);
self.index += count as u64;
Ok(())
}
}
#[inline(always)]
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
self.readbytes(self.bytes.len() as u64 - self.index)
}
}

View File

@ -4,30 +4,30 @@ pub mod writer;
pub use reader::TextReader; pub use reader::TextReader;
pub use writer::TextWriter; pub use writer::TextWriter;
use crate::value::reader::BytesBinarySource; use crate::value::source::BytesBinarySource;
use std::io; use std::io;
use super::{DomainParse, IOValue, IOValueDomainCodec, NestedValue, Reader, ViaCodec}; use super::{DomainDecode, IOValue, IOValueDomainCodec, NestedValue, Reader};
pub fn from_str<N: NestedValue, Dec: DomainParse<N::Embedded>>( pub fn from_str<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
s: &str, s: &str,
decode_embedded: Dec, decode_embedded: &mut Dec,
) -> io::Result<N> { ) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes()), decode_embedded).demand_next(false) TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next(false, decode_embedded)
} }
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> { pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
from_str(s, ViaCodec::new(IOValueDomainCodec)) from_str(s, &mut IOValueDomainCodec)
} }
pub fn annotated_from_str<N: NestedValue, Dec: DomainParse<N::Embedded>>( pub fn annotated_from_str<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
s: &str, s: &str,
decode_embedded: Dec, decode_embedded: &mut Dec,
) -> io::Result<N> { ) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes()), decode_embedded).demand_next(true) TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next(true, decode_embedded)
} }
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> { pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
annotated_from_str(s, ViaCodec::new(IOValueDomainCodec)) annotated_from_str(s, &mut IOValueDomainCodec)
} }

View File

@ -1,18 +1,12 @@
use crate::error::Error; use crate::error::Error;
use crate::error::ExpectedKind; use crate::error::ExpectedKind;
use crate::error::Received; use crate::error::io_eof;
use crate::error::io_syntax_error; use crate::error::io_syntax_error;
use crate::error::is_eof_io_error;
use crate::error::syntax_error;
use crate::hex; use crate::hex;
use crate::value::CompoundClass; use crate::value::CompoundClass;
use crate::value::DomainParse; use crate::value::DomainDecode;
use crate::value::DummyValue;
use crate::value::Embeddable;
use crate::value::IOValue;
use crate::value::IOValueDomainCodec;
use crate::value::Map; use crate::value::Map;
use crate::value::NestedValue; use crate::value::NestedValue;
use crate::value::Reader; use crate::value::Reader;
@ -20,11 +14,10 @@ use crate::value::Record;
use crate::value::Set; use crate::value::Set;
use crate::value::Token; use crate::value::Token;
use crate::value::Value; use crate::value::Value;
use crate::value::ViaCodec;
use crate::value::boundary as B; use crate::value::boundary as B;
use crate::value::reader::BinarySource;
use crate::value::reader::ReaderResult; use crate::value::reader::ReaderResult;
use crate::value::repr::Annotations; use crate::value::repr::Annotations;
use crate::value::source::BinarySource;
use num::bigint::BigInt; use num::bigint::BigInt;
@ -32,10 +25,9 @@ use std::io;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::marker::PhantomData; use std::marker::PhantomData;
pub struct TextReader<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>> { pub struct TextReader<'de, 'src, S: BinarySource<'de>> {
pub source: &'src mut S, pub source: &'src mut S,
pub dec: Dec, phantom: PhantomData<&'de ()>,
phantom: PhantomData<&'de D>,
} }
fn decode_utf8(bs: Vec<u8>) -> io::Result<String> { fn decode_utf8(bs: Vec<u8>) -> io::Result<String> {
@ -50,34 +42,36 @@ 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, S: BinarySource<'de>> TextReader<'de, 'src, S> {
TextReader<'de, 'src, D, Dec, S> pub fn new(source: &'src mut S) -> Self {
{
pub fn new(source: &'src mut S, dec: Dec) -> Self {
TextReader { TextReader {
source, source,
dec,
phantom: PhantomData, phantom: PhantomData,
} }
} }
fn peek(&mut self) -> io::Result<u8> { fn peek(&mut self) -> io::Result<Option<u8>> {
self.source.peek() self.source.peek()
} }
#[inline(always)]
fn peek_noeof(&mut self) -> io::Result<u8> {
self.source.peek()?.ok_or_else(|| io_eof())
}
fn skip(&mut self) -> io::Result<()> { fn skip(&mut self) -> io::Result<()> {
self.source.skip() self.source.skip()
} }
fn next_byte(&mut self) -> io::Result<u8> { fn next_byte(&mut self) -> io::Result<u8> {
let b = self.source.peek()?; let b = self.peek_noeof()?;
self.source.skip()?; self.source.skip()?;
Ok(b) Ok(b)
} }
fn skip_whitespace(&mut self) { fn skip_whitespace(&mut self) {
// Deliberately swallows errors. // Deliberately swallows errors.
while let Ok(c) = self.peek() { while let Ok(Some(c)) = self.peek() {
match c { match c {
b' ' | b'\t' | b'\r' | b'\n' | b',' => { b' ' | b'\t' | b'\r' | b'\n' | b',' => {
let _ = self.skip(); let _ = self.skip();
@ -88,21 +82,20 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} }
} }
// TODO: This is a duplicate of fn expected in PackedReader. fn expected(&mut self, k: ExpectedKind) -> Error {
fn expected<N: NestedValue<Embedded = D>>(&mut self, k: ExpectedKind) -> Error { Error::Expected(k)
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<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
decode_embedded: &mut Dec,
) -> ReaderResult<Vec<N>> {
let mut vs = Vec::new(); let mut vs = Vec::new();
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
match self.peek()? { match self.peek_noeof()? {
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) } b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) }
b'@' => { self.skip()?; vs.push(self.demand_next(true)?) } b'@' => { self.skip()?; vs.push(self.demand_next(true, decode_embedded)?) }
_ => return Ok(vs), _ => return Ok(vs),
} }
} }
@ -111,24 +104,18 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn skip_annotations(&mut self) -> ReaderResult<()> { fn skip_annotations(&mut self) -> ReaderResult<()> {
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
match self.peek()? { match self.peek_noeof()? {
b';' => { self.skip()?; self.comment_line()?; }, b';' => { self.skip()?; self.comment_line()?; },
b'@' => { self.skip()?; Reader::<DummyValue<D>>::skip_value(self)?; }, b'@' => { self.skip()?; self.skip_value()?; },
_ => return Ok(()), _ => return Ok(()),
} }
} }
} }
pub fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
let mut r = TextReader::new(self.source, ViaCodec::new(IOValueDomainCodec));
let v = r.demand_next(read_annotations)?;
Ok(v)
}
fn comment_line(&mut self) -> io::Result<String> { fn comment_line(&mut self) -> io::Result<String> {
let mut bs = Vec::new(); let mut bs = Vec::new();
loop { loop {
let b = self.peek()?; let b = self.peek_noeof()?;
self.skip()?; self.skip()?;
match b { match b {
b'\r' | b'\n' => return Ok(decode_utf8(bs)?), b'\r' | b'\n' => return Ok(decode_utf8(bs)?),
@ -152,7 +139,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn read_fracexp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> { fn read_fracexp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
let mut is_float = false; let mut is_float = false;
match self.peek() { match self.peek_noeof() {
Ok(b'.') => { Ok(b'.') => {
is_float = true; is_float = true;
bs.push(self.next_byte()?); bs.push(self.next_byte()?);
@ -161,7 +148,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} }
_ => () _ => ()
} }
match self.peek() { match self.peek_noeof() {
Ok(b'e') | Ok(b'E') => { Ok(b'e') | Ok(b'E') => {
bs.push(self.next_byte()?); bs.push(self.next_byte()?);
self.read_sign_and_exp(bs) self.read_sign_and_exp(bs)
@ -171,7 +158,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} }
fn read_sign_and_exp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> { fn read_sign_and_exp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
match self.peek()? { match self.peek_noeof()? {
b'+' | b'-' => bs.push(self.next_byte()?), b'+' | b'-' => bs.push(self.next_byte()?),
_ => (), _ => (),
} }
@ -183,7 +170,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn finish_number<N: NestedValue>(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<N> { fn finish_number<N: NestedValue>(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<N> {
let s = decode_utf8(bs)?; let s = decode_utf8(bs)?;
if is_float { if is_float {
match self.peek() { match self.peek_noeof() {
Ok(b'f') | Ok(b'F') => { Ok(b'f') | Ok(b'F') => {
self.skip()?; self.skip()?;
Ok(N::new(s.parse::<f32>().map_err( Ok(N::new(s.parse::<f32>().map_err(
@ -208,7 +195,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
return Err(io_syntax_error("Incomplete number")); return Err(io_syntax_error("Incomplete number"));
} }
bs.push(c); bs.push(c);
while let Ok(c) = self.peek() { while let Ok(Some(c)) = self.peek() {
if !(c as char).is_digit(10) { if !(c as char).is_digit(10) {
break; break;
} }
@ -334,43 +321,51 @@ 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<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
delimiter: u8,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Vec<N>> {
let mut vs = Vec::new(); let mut vs = Vec::new();
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
if self.peek()? == delimiter { if self.peek()? == Some(delimiter) {
self.skip()?; self.skip()?;
return Ok(vs); return Ok(vs);
} }
vs.push(Reader::<N>::demand_next(self, read_annotations)?); vs.push(self.demand_next(read_annotations, decode_embedded)?);
} }
} }
fn read_dictionary<N: NestedValue<Embedded = D>>(&mut self, read_annotations: bool) -> io::Result<N> { fn read_dictionary<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
let mut d = Map::new(); let mut d = Map::new();
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
if self.peek()? == b'}' { if self.peek_noeof()? == b'}' {
self.skip()?; self.skip()?;
return Ok(N::new(d)); return Ok(N::new(d));
} }
let k = Reader::<N>::demand_next(self, read_annotations)?; let k = self.demand_next(read_annotations, decode_embedded)?;
self.skip_whitespace(); self.skip_whitespace();
if self.next_byte()? != b':' { if self.next_byte()? != b':' {
return Err(io_syntax_error("Missing expected key/value separator")); return Err(io_syntax_error("Missing expected key/value separator"));
} }
let v = Reader::<N>::demand_next(self, read_annotations)?; let v = self.demand_next(read_annotations, decode_embedded)?;
d.insert(k, v); d.insert(k, v);
} }
} }
fn read_raw_symbol<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> { fn read_raw_symbol<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
loop { loop {
let c = match self.peek() { let c = match self.peek()? {
Err(e) if is_eof_io_error(&e) => b' ', None => b' ',
Err(e) => return Err(e)?, Some(c) if (c as char).is_whitespace() => b' ',
Ok(c) if (c as char).is_whitespace() => b' ', Some(c) => c
Ok(c) => c
}; };
match c { match c {
b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' | b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' |
@ -385,15 +380,16 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} }
} }
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'de>> impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for TextReader<'de, 'src, S> {
Reader<'de, N> for TextReader<'de, 'src, N::Embedded, Dec, S> fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
{ &mut self,
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> { read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
self.skip_whitespace(); self.skip_whitespace();
let c = match self.peek() { let c = match self.peek()? {
Ok(c) => c, None => return Ok(None),
Err(e) if is_eof_io_error(&e) => return Ok(None), Some(c) => c,
Err(e) => return Err(e.into()),
}; };
Ok(Some(match c { Ok(Some(match c {
b'-' => { b'-' => {
@ -415,14 +411,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
} }
b';' | b'@' => { b';' | b'@' => {
if read_annotations { if read_annotations {
let mut annotations = self.gather_annotations()?; let mut annotations = self.gather_annotations(decode_embedded)?;
let (existing_annotations, v) = let av: N = self.demand_next(read_annotations, decode_embedded)?;
Reader::<N>::demand_next(self, read_annotations)?.pieces(); let (existing_annotations, v) = av.pieces();
annotations.extend_from_slice(existing_annotations.slice()); annotations.extend_from_slice(existing_annotations.slice());
N::wrap(Annotations::new(Some(annotations)), v) N::wrap(Annotations::new(Some(annotations)), v)
} else { } else {
self.skip_annotations()?; self.skip_annotations()?;
self.demand_next(read_annotations)? self.demand_next(read_annotations, decode_embedded)?
} }
} }
b':' => { b':' => {
@ -433,7 +429,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
match self.next_byte()? { match self.next_byte()? {
b'f' => N::new(false), b'f' => N::new(false),
b't' => N::new(true), b't' => N::new(true),
b'{' => N::new(Set::from_iter(self.upto(b'}', read_annotations)?.into_iter())), b'{' => N::new(Set::from_iter(
self.upto(b'}', read_annotations, decode_embedded)?.into_iter())),
b'"' => self.read_literal_binary()?, b'"' => self.read_literal_binary()?,
b'x' => if self.next_byte()? == b'"' { b'x' => if self.next_byte()? == b'"' {
self.read_hex_binary()? self.read_hex_binary()?
@ -442,7 +439,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}, },
b'[' => self.read_base64_binary()?, b'[' => self.read_base64_binary()?,
b'=' => { b'=' => {
let bs_val: N = self.demand_next(true)?; let bs_val = self.next_iovalue(true)?;
if bs_val.annotations().slice().len() > 0 { if bs_val.annotations().slice().len() > 0 {
return Err(io_syntax_error("Annotations not permitted after #=")); return Err(io_syntax_error("Annotations not permitted after #="));
} }
@ -451,20 +448,18 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
return Err(io_syntax_error("ByteString must follow #=")), return Err(io_syntax_error("ByteString must follow #=")),
Some(bs) => Some(bs) =>
crate::value::BytesBinarySource::new(bs) crate::value::BytesBinarySource::new(bs)
.packed(ViaCodec::new(&mut self.dec)) .packed()
.demand_next(read_annotations)? .demand_next(read_annotations, decode_embedded)?
} }
} }
b'!' => { b'!' => Value::Embedded(
let v = self.next_iovalue(read_annotations)?; decode_embedded.decode_embedded(self, read_annotations)?).wrap(),
Value::Embedded(self.dec.parse_embedded(&v)?).wrap()
}
other => return Err(io_syntax_error(&format!("Invalid # syntax: {:?}", other))), other => return Err(io_syntax_error(&format!("Invalid # syntax: {:?}", other))),
} }
} }
b'<' => { b'<' => {
self.skip()?; self.skip()?;
let vs = self.upto(b'>', read_annotations)?; let vs = self.upto(b'>', read_annotations, decode_embedded)?;
if vs.is_empty() { if vs.is_empty() {
return Err(io_syntax_error("Missing record label")); return Err(io_syntax_error("Missing record label"));
} }
@ -472,11 +467,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
} }
b'[' => { b'[' => {
self.skip()?; self.skip()?;
N::new(self.upto(b']', read_annotations)?) N::new(self.upto(b']', read_annotations, decode_embedded)?)
} }
b'{' => { b'{' => {
self.skip()?; self.skip()?;
self.read_dictionary(read_annotations)? self.read_dictionary(read_annotations, decode_embedded)?
} }
b'>' => return Err(io_syntax_error("Unexpected >")), b'>' => return Err(io_syntax_error("Unexpected >")),
b']' => return Err(io_syntax_error("Unexpected ]")), b']' => return Err(io_syntax_error("Unexpected ]")),
@ -488,40 +483,23 @@ 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) -> ReaderResult<()> {
self.skip_annotations()?; self.skip_annotations()?;
if self.peek()? != b'<' { return Err(self.expected::<N>(ExpectedKind::Record(arity))); } if self.peek()? != Some(b'<') { return Err(self.expected(ExpectedKind::Record)); }
self.skip()?; self.skip()?;
let mut b = B::Type::default(); Ok(())
Reader::<N>::ensure_more_expected(self, &mut b, &B::Item::RecordLabel)?;
Ok(b)
}
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'{' => return Ok(B::Item::SetValue),
_ => (),
},
b'[' => return Ok(B::Item::SequenceValue),
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::SequenceOrSet))
} }
fn open_sequence(&mut self) -> ReaderResult<()> { fn open_sequence(&mut self) -> ReaderResult<()> {
self.skip_annotations()?; self.skip_annotations()?;
if self.peek()? != b'[' { return Err(self.expected::<N>(ExpectedKind::Sequence)); } if self.peek()? != Some(b'[') { return Err(self.expected(ExpectedKind::Sequence)); }
self.skip()?; self.skip()?;
Ok(()) Ok(())
} }
fn open_set(&mut self) -> ReaderResult<()> { fn open_set(&mut self) -> ReaderResult<()> {
self.skip_annotations()?; self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?; let mark = self.mark()?;
match self.next_byte()? { match self.next_byte()? {
b'#' => match self.next_byte()? { b'#' => match self.next_byte()? {
b'{' => return Ok(()), b'{' => return Ok(()),
@ -529,13 +507,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}, },
_ => (), _ => (),
} }
Reader::<N>::restore(self, &mark)?; self.restore(&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'{' { return Err(self.expected::<N>(ExpectedKind::Dictionary)); } if self.peek()? != Some(b'{') { return Err(self.expected(ExpectedKind::Dictionary)); }
self.skip()?; self.skip()?;
Ok(()) Ok(())
} }
@ -549,7 +527,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
} => { } => {
self.skip_whitespace(); self.skip_whitespace();
if self.next_byte()? != b':' { if self.next_byte()? != b':' {
return Err(syntax_error("Missing expected key/value separator")); return Err(io_syntax_error("Missing expected key/value separator"))?;
} }
}, },
_ => (), _ => (),
@ -559,14 +537,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool> { fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool> {
self.skip_whitespace(); self.skip_whitespace();
match self.peek()? { match self.peek_noeof()? {
b'>' | b']' | b'}' => { b'>' | b']' | b'}' => {
self.skip()?; self.skip()?;
Ok(true) Ok(true)
} }
_ => { _ => {
b.shift(Some(i.clone())); b.shift(Some(i.clone()));
Reader::<N>::boundary(self, b)?; self.boundary(b)?;
Ok(false) Ok(false)
} }
} }
@ -574,7 +552,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_embedded(&mut self) -> ReaderResult<()> { fn open_embedded(&mut self) -> ReaderResult<()> {
self.skip_annotations()?; self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?; let mark = self.mark()?;
match self.next_byte()? { match self.next_byte()? {
b'#' => match self.next_byte()? { b'#' => match self.next_byte()? {
b'!' => return Ok(()), b'!' => return Ok(()),
@ -582,8 +560,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}, },
_ => (), _ => (),
} }
Reader::<N>::restore(self, &mark)?; self.restore(&mark)?;
Err(self.expected::<N>(ExpectedKind::Embedded)) Err(self.expected(ExpectedKind::Embedded))
} }
fn close_embedded(&mut self) -> ReaderResult<()> { fn close_embedded(&mut self) -> ReaderResult<()> {
@ -600,9 +578,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
self.source.restore(mark) self.source.restore(mark)
} }
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> { fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>> {
self.skip_annotations()?; self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?; let mark = self.mark()?;
Ok(match self.next_byte()? { Ok(match self.next_byte()? {
b'<' => Token::Compound(CompoundClass::Record), b'<' => Token::Compound(CompoundClass::Record),
b'[' => Token::Compound(CompoundClass::Sequence), b'[' => Token::Compound(CompoundClass::Sequence),
@ -611,25 +593,18 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
b']' => Token::End, b']' => Token::End,
b'}' => Token::End, b'}' => Token::End,
b'#' => match self.next_byte()? { b'#' => match self.next_byte()? {
b'!' => { b'!' => Token::Embedded(decode_embedded.decode_embedded(
let v = self.next_iovalue(read_embedded_annotations)?; self, read_embedded_annotations)?),
Token::Embedded(self.dec.parse_embedded(&v)?)
}
b'{' => Token::Compound(CompoundClass::Set), b'{' => Token::Compound(CompoundClass::Set),
_ => { _ => {
Reader::<N>::restore(self, &mark)?; self.restore(&mark)?;
Token::Atom(self.demand_next(false)?) Token::Atom(self.demand_next(false, decode_embedded)?)
} }
}, },
_ => { _ => {
Reader::<N>::restore(self, &mark)?; self.restore(&mark)?;
Token::Atom(self.demand_next(false)?) Token::Atom(self.demand_next(false, decode_embedded)?)
} }
}) })
} }
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
let annotations = self.gather_annotations()?;
Ok((annotations, self.next_token(true)?))
}
} }

View File

@ -3,8 +3,6 @@ use crate::value::IOValue;
use crate::value::IOValueDomainCodec; use crate::value::IOValueDomainCodec;
use crate::value::NestedValue; use crate::value::NestedValue;
use crate::value::Writer; use crate::value::Writer;
use crate::value::suspendable::Suspendable;
use crate::value::writer::CompoundWriter;
use num::bigint::BigInt; use num::bigint::BigInt;
@ -20,7 +18,7 @@ pub enum CommaStyle {
} }
pub struct TextWriter<W: io::Write> { pub struct TextWriter<W: io::Write> {
w: Suspendable<W>, w: W,
pub comma_style: CommaStyle, pub comma_style: CommaStyle,
pub indentation: usize, pub indentation: usize,
pub escape_spaces: bool, pub escape_spaces: bool,
@ -51,7 +49,7 @@ impl TextWriter<&mut Vec<u8>> {
impl<W: io::Write> TextWriter<W> { impl<W: io::Write> TextWriter<W> {
pub fn new(w: W) -> Self { pub fn new(w: W) -> Self {
TextWriter { TextWriter {
w: Suspendable::new(w), w,
comma_style: CommaStyle::default(), comma_style: CommaStyle::default(),
indentation: 0, indentation: 0,
escape_spaces: false, escape_spaces: false,
@ -69,14 +67,6 @@ impl<W: io::Write> TextWriter<W> {
self self
} }
pub fn suspend(&mut self) -> Self {
TextWriter { w: self.w.suspend(), indent: self.indent.clone(), .. *self }
}
pub fn resume(&mut self, other: Self) {
self.w.resume(other.w)
}
pub fn write_stringlike_char_fallback<F>( pub fn write_stringlike_char_fallback<F>(
&mut self, &mut self,
c: char, c: char,
@ -132,7 +122,14 @@ impl<W: io::Write> TextWriter<W> {
} }
} }
impl<W: io::Write> CompoundWriter for TextWriter<W> { macro_rules! simple_writer_method {
($n:ident, $argty:ty) =>
(fn $n (&mut self, v: $argty) -> io::Result<()> {
write!(self.w, "{}", v)
});
}
impl<W: io::Write> Writer for TextWriter<W> {
#[inline] #[inline]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> { fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match (b.closing.as_ref(), b.opening.as_ref()) { match (b.closing.as_ref(), b.opening.as_ref()) {
@ -187,29 +184,12 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
Ok(()) Ok(())
} }
}
macro_rules! simple_writer_method { fn start_annotations(&mut self) -> io::Result<()> {
($n:ident, $argty:ty) => Ok(())
(fn $n (&mut self, v: $argty) -> io::Result<()> {
write!(self.w, "{}", v)
});
}
impl<W: io::Write> Writer for TextWriter<W> {
type AnnWriter = Self;
type RecWriter = Self;
type SeqWriter = Self;
type SetWriter = Self;
type DictWriter = Self;
type EmbeddedWriter = Self;
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.suspend())
} }
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> { fn end_annotations(&mut self) -> io::Result<()> {
self.resume(ann);
Ok(()) Ok(())
} }
@ -218,12 +198,12 @@ impl<W: io::Write> Writer for TextWriter<W> {
} }
fn write_f32(&mut self, v: f32) -> io::Result<()> { fn write_f32(&mut self, v: f32) -> io::Result<()> {
dtoa::write(&mut *self.w, v)?; dtoa::write(&mut self.w, v)?;
write!(self.w, "f") write!(self.w, "f")
} }
fn write_f64(&mut self, v: f64) -> io::Result<()> { fn write_f64(&mut self, v: f64) -> io::Result<()> {
dtoa::write(&mut *self.w, v)?; dtoa::write(&mut self.w, v)?;
Ok(()) Ok(())
} }
@ -273,53 +253,48 @@ impl<W: io::Write> Writer for TextWriter<W> {
} }
} }
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> { fn start_record(&mut self) -> io::Result<()> {
write!(self.w, "<")?; write!(self.w, "<")?;
Ok(self.suspend()) Ok(())
} }
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> { fn end_record(&mut self) -> io::Result<()> {
self.resume(rec);
write!(self.w, ">") write!(self.w, ">")
} }
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> { fn start_sequence(&mut self) -> io::Result<()> {
write!(self.w, "[")?; write!(self.w, "[")?;
Ok(self.suspend()) Ok(())
} }
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> { fn end_sequence(&mut self) -> io::Result<()> {
self.resume(seq);
write!(self.w, "]") write!(self.w, "]")
} }
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> { fn start_set(&mut self) -> io::Result<()> {
write!(self.w, "#{{")?; write!(self.w, "#{{")?;
Ok(self.suspend()) Ok(())
} }
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> { fn end_set(&mut self) -> io::Result<()> {
self.resume(set);
write!(self.w, "}}") write!(self.w, "}}")
} }
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> { fn start_dictionary(&mut self) -> io::Result<()> {
write!(self.w, "{{")?; write!(self.w, "{{")?;
Ok(self.suspend()) Ok(())
} }
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> { fn end_dictionary(&mut self) -> io::Result<()> {
self.resume(dict);
write!(self.w, "}}") write!(self.w, "}}")
} }
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> { fn start_embedded(&mut self) -> io::Result<()> {
write!(self.w, "#!")?; write!(self.w, "#!")?;
Ok(self.suspend()) Ok(())
} }
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> { fn end_embedded(&mut self) -> io::Result<()> {
self.resume(ptr);
Ok(()) Ok(())
} }

View File

@ -5,20 +5,9 @@ use super::boundary as B;
use super::signed_integer::SignedIntegerRepr; use super::signed_integer::SignedIntegerRepr;
use super::repr::{Value, NestedValue, Float, Double}; use super::repr::{Value, NestedValue, Float, Double};
pub trait CompoundWriter: Writer {
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
}
pub trait Writer: Sized { pub trait Writer: Sized {
type AnnWriter: CompoundWriter; fn start_annotations(&mut self) -> io::Result<()>;
type RecWriter: CompoundWriter; fn end_annotations(&mut self) -> io::Result<()>;
type SeqWriter: CompoundWriter;
type SetWriter: CompoundWriter;
type DictWriter: CompoundWriter;
type EmbeddedWriter: Writer;
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter>;
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()>;
fn write_bool(&mut self, v: bool) -> io::Result<()>; fn write_bool(&mut self, v: bool) -> io::Result<()>;
@ -41,48 +30,59 @@ pub trait Writer: Sized {
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()>; fn write_bytes(&mut self, v: &[u8]) -> io::Result<()>;
fn write_symbol(&mut self, v: &str) -> io::Result<()>; fn write_symbol(&mut self, v: &str) -> io::Result<()>;
fn start_record(&mut self, field_count: Option<usize>) -> io::Result<Self::RecWriter>; fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()>;
fn start_sequence(&mut self, item_count: Option<usize>) -> io::Result<Self::SeqWriter>; fn start_record(&mut self) -> io::Result<()>;
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()>; fn end_record(&mut self) -> io::Result<()>;
fn start_set(&mut self, item_count: Option<usize>) -> io::Result<Self::SetWriter>; fn start_sequence(&mut self) -> io::Result<()>;
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()>; fn end_sequence(&mut self) -> io::Result<()>;
fn start_dictionary(&mut self, entry_count: Option<usize>) -> io::Result<Self::DictWriter>; fn start_set(&mut self) -> io::Result<()>;
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()>; fn end_set(&mut self) -> io::Result<()>;
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter>; fn start_dictionary(&mut self) -> io::Result<()>;
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()>; fn end_dictionary(&mut self) -> io::Result<()>;
fn start_embedded(&mut self) -> io::Result<()>;
fn end_embedded(&mut self) -> io::Result<()>;
fn flush(&mut self) -> io::Result<()>; fn flush(&mut self) -> io::Result<()>;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#[inline(always)]
fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>( fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self, &mut self,
enc: &mut Enc, enc: &mut Enc,
v: &N, v: &N,
) -> io::Result<()> {
self.inner_write(enc, v)
}
fn inner_write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> { ) -> io::Result<()> {
match v.annotations().maybe_slice() { match v.annotations().maybe_slice() {
None => { None => {
self.write_value(enc, v.value())?; self.write_value(enc, v.value())?;
} }
Some(anns) => { Some(anns) => {
let mut a = self.start_annotations()?; self.start_annotations()?;
let mut b = B::Type::default(); let mut b = B::Type::default();
for ann in anns { for ann in anns {
b.shift(Some(B::Item::Annotation)); b.shift(Some(B::Item::Annotation));
a.boundary(&b)?; self.boundary(&b)?;
a.write(enc, ann)?; self.inner_write(enc, ann)?;
} }
b.shift(Some(B::Item::AnnotatedValue)); b.shift(Some(B::Item::AnnotatedValue));
a.boundary(&b)?; self.boundary(&b)?;
a.write_value(enc, v.value())?; self.write_value(enc, v.value())?;
b.shift(None); b.shift(None);
a.boundary(&b)?; self.boundary(&b)?;
self.end_annotations(a)?; self.end_annotations()?;
} }
} }
Ok(()) Ok(())
@ -106,77 +106,63 @@ pub trait Writer: Sized {
Value::ByteString(bs) => self.write_bytes(bs), Value::ByteString(bs) => self.write_bytes(bs),
Value::Symbol(s) => self.write_symbol(s), Value::Symbol(s) => self.write_symbol(s),
Value::Record(r) => { Value::Record(r) => {
let mut c = self.start_record(Some(r.arity()))?; self.start_record()?;
let mut b = B::start(B::Item::RecordLabel); let mut b = B::start(B::Item::RecordLabel);
c.boundary(&b)?; self.boundary(&b)?;
c.write(enc, r.label())?; self.inner_write(enc, r.label())?;
for f in r.fields() { for f in r.fields() {
b.shift(Some(B::Item::RecordField)); b.shift(Some(B::Item::RecordField));
c.boundary(&b)?; self.boundary(&b)?;
c.write(enc, f)?; self.inner_write(enc, f)?;
} }
b.shift(None); b.shift(None);
c.boundary(&b)?; self.boundary(&b)?;
self.end_record(c) self.end_record()
} }
Value::Sequence(vs) => { Value::Sequence(vs) => {
let mut c = self.start_sequence(Some(vs.len()))?; self.start_sequence()?;
let mut b = B::Type::default(); let mut b = B::Type::default();
for v in vs { for v in vs {
b.shift(Some(B::Item::SequenceValue)); b.shift(Some(B::Item::SequenceValue));
c.boundary(&b)?; self.boundary(&b)?;
c.write(enc, v)?; self.inner_write(enc, v)?;
} }
b.shift(None); b.shift(None);
c.boundary(&b)?; self.boundary(&b)?;
self.end_sequence(c) self.end_sequence()
} }
Value::Set(vs) => { Value::Set(vs) => {
let mut c = self.start_set(Some(vs.len()))?; self.start_set()?;
let mut b = B::Type::default(); let mut b = B::Type::default();
for v in vs { for v in vs {
b.shift(Some(B::Item::SetValue)); b.shift(Some(B::Item::SetValue));
c.boundary(&b)?; self.boundary(&b)?;
c.write(enc, v)?; self.inner_write(enc, v)?;
} }
b.shift(None); b.shift(None);
c.boundary(&b)?; self.boundary(&b)?;
self.end_set(c) self.end_set()
} }
Value::Dictionary(vs) => { Value::Dictionary(vs) => {
let mut c = self.start_dictionary(Some(vs.len()))?; self.start_dictionary()?;
let mut b = B::Type::default(); let mut b = B::Type::default();
for (k, v) in vs { for (k, v) in vs {
b.shift(Some(B::Item::DictionaryKey)); b.shift(Some(B::Item::DictionaryKey));
c.boundary(&b)?; self.boundary(&b)?;
c.write(enc, k)?; self.inner_write(enc, k)?;
b.shift(Some(B::Item::DictionaryValue)); b.shift(Some(B::Item::DictionaryValue));
c.boundary(&b)?; self.boundary(&b)?;
c.write(enc, v)?; self.inner_write(enc, v)?;
} }
b.shift(None); b.shift(None);
c.boundary(&b)?; self.boundary(&b)?;
self.end_dictionary(c) self.end_dictionary()
} }
Value::Embedded(d) => { Value::Embedded(d) => {
let mut c = self.start_embedded()?; self.start_embedded()?;
enc.encode_embedded(&mut c, d)?; enc.encode_embedded(self, d)?;
self.end_embedded(c) self.end_embedded()
} }
} }
} }
} }
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {
let mut byte_count = 0;
loop {
byte_count += 1;
if v < 128 {
w.write_all(&[v as u8])?;
return Ok(byte_count);
} else {
w.write_all(&[((v & 0x7f) + 128) as u8])?;
v >>= 7;
}
}
}

View File

@ -14,7 +14,7 @@ mod samples;
use samples::*; use samples::*;
fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> { fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
BytesBinarySource::new(bytes).packed_iovalues().configured(true).collect() BytesBinarySource::new(bytes).packed().iovalues().collect()
} }
#[test] fn compare_text_with_packed() -> io::Result<()> { #[test] fn compare_text_with_packed() -> io::Result<()> {
@ -23,14 +23,11 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
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()).text().next_iovalue(true)?
&mut BytesBinarySource::new(contents.as_bytes()),
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec))
.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();
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true)? IOBinarySource::new(&mut fh).packed().next_iovalue(true)?
}; };
assert_eq!(from_text, from_packed); assert_eq!(from_text, from_packed);
Ok(()) Ok(())
@ -105,7 +102,7 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
#[test] fn run() -> io::Result<()> { #[test] fn run() -> 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 src = IOBinarySource::new(&mut fh); let mut src = IOBinarySource::new(&mut fh);
let mut d = src.packed_iovalues().configured(true); let mut d = src.packed().iovalues();
let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap(); let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap();
for (Symbol(ref name), ref case) in tests.tests { for (Symbol(ref name), ref case) in tests.tests {
@ -143,14 +140,14 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
} }
} }
TestCase::DecodeShort(ref bin) => { TestCase::DecodeShort(ref bin) => {
assert!(if let Err(e) = BytesBinarySource::new(bin).packed_iovalues().configured(true).next().unwrap() { assert!(if let Err(e) = BytesBinarySource::new(bin).packed().iovalues().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!(BytesBinarySource::new(bin).packed_iovalues().configured(true).next().is_none()); assert!(BytesBinarySource::new(bin).packed().iovalues().next().is_none());
} }
} }
} }