Blue Rust implementation (WIP)
This commit is contained in:
parent
d22d0d7120
commit
c2a48a9b78
|
@ -108,8 +108,9 @@ pub struct CompilerConfig {
|
|||
pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> {
|
||||
let mut f = File::open(&i)?;
|
||||
let mut src = IOBinarySource::new(&mut f);
|
||||
let mut reader = src.packed_iovalues();
|
||||
let blob = reader.demand_next(false)?;
|
||||
let mut reader = src.packed().iovalues();
|
||||
reader.set_read_annotations(false);
|
||||
let blob = reader.demand_next()?;
|
||||
let language = Language::default();
|
||||
|
||||
if let Ok(s) = language.parse(&blob) {
|
||||
|
@ -139,8 +140,8 @@ impl CompilerConfig {
|
|||
) -> Self {
|
||||
CompilerConfig {
|
||||
bundle: Map::new(),
|
||||
output_dir: output_dir,
|
||||
fully_qualified_module_prefix: fully_qualified_module_prefix,
|
||||
output_dir,
|
||||
fully_qualified_module_prefix,
|
||||
support_crate: "preserves_schema".to_owned(),
|
||||
external_modules: Map::new(),
|
||||
plugins: vec![
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,8 +42,9 @@ mod tests {
|
|||
|
||||
let mut f = std::fs::File::open("../../../schema/schema.bin")?;
|
||||
let mut src = IOBinarySource::new(&mut f);
|
||||
let mut reader = src.packed_iovalues();
|
||||
let schema = reader.demand_next(false)?;
|
||||
let mut reader = src.packed().iovalues();
|
||||
reader.set_read_annotations(false);
|
||||
let schema = reader.demand_next()?;
|
||||
let language = crate::gen::Language::default();
|
||||
let parsed = Schema::parse(&language, &schema).expect("successful parse");
|
||||
assert_eq!(schema, parsed.unparse(&language));
|
||||
|
|
|
@ -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> {
|
||||
panic!("Not yet implemented");
|
||||
todo!("Not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
pub use lazy_static::lazy_static;
|
||||
|
||||
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::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
|
||||
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> {
|
||||
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec)
|
||||
preserves::value::packed::from_bytes(bs, &mut NoEmbeddedDomainCodec)
|
||||
}
|
||||
|
||||
pub fn decode_embedded<D: Domain>(
|
||||
|
@ -100,7 +103,7 @@ pub enum ParseError {
|
|||
impl From<preserves::error::Error> for ParseError {
|
||||
fn from(v: preserves::error::Error) -> Self {
|
||||
match v {
|
||||
preserves::error::Error::Expected(_, _) =>
|
||||
preserves::error::Error::Expected(_) =>
|
||||
ParseError::ConformanceError("preserves::error::Error::Expected"),
|
||||
_ =>
|
||||
ParseError::Preserves(v),
|
||||
|
|
|
@ -33,7 +33,7 @@ enum Variety {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?;
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -6,14 +6,15 @@ use std::io;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use super::value::boundary as B;
|
||||
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec};
|
||||
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
|
||||
use super::value::{IOValueDomainCodec, PackedReader, TextReader};
|
||||
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 struct Deserializer<'de, 'r, R: Reader<'de, IOValue>> {
|
||||
pub struct Deserializer<'de, 'r, R: Reader<'de>> {
|
||||
pub read: &'r mut R,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
@ -23,12 +24,11 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
|
|||
where
|
||||
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> {
|
||||
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes()),
|
||||
ViaCodec::new(IOValueDomainCodec)))
|
||||
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes())))
|
||||
}
|
||||
|
||||
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
|
||||
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>
|
||||
where
|
||||
T: Deserialize<'de>
|
||||
|
@ -49,13 +49,29 @@ where
|
|||
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 {
|
||||
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>
|
||||
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>
|
||||
{
|
||||
if let Some(mut b) = self.read.open_option()? {
|
||||
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)
|
||||
} else {
|
||||
Ok(visitor.visit_none::<Error>()?)
|
||||
let mut b = self.open_record()?;
|
||||
match self.read.next_symbol()?.as_ref() {
|
||||
"None" => {
|
||||
self.read.ensure_complete(b, &B::Item::RecordField)?;
|
||||
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>
|
||||
{
|
||||
let b = self.read.open_simple_record("tuple", Some(0))?;
|
||||
let b = self.open_simple_record("tuple")?;
|
||||
let result = visitor.visit_unit::<Error>()?;
|
||||
self.read.ensure_complete(b, &B::Item::RecordField)?;
|
||||
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)
|
||||
-> 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>()?;
|
||||
self.read.ensure_complete(b, &B::Item::RecordField)?;
|
||||
Ok(result)
|
||||
|
@ -186,11 +209,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
|
|||
-> Result<V::Value> where V: Visitor<'de>
|
||||
{
|
||||
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),
|
||||
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)?;
|
||||
let result = visitor.visit_newtype_struct(&mut *self)?;
|
||||
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> {
|
||||
// Hack around serde's model: Deserialize *sets* as sequences,
|
||||
// too, and reconstruct them as Rust Sets on the visitor side.
|
||||
let i = self.read.open_sequence_or_set()?;
|
||||
visitor.visit_seq(Seq::new(self, B::Type::default(), i))
|
||||
let mark = self.read.mark()?;
|
||||
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 result = visitor.visit_seq(&mut seq)?;
|
||||
seq.skip_remainder()?;
|
||||
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>
|
||||
{
|
||||
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 result = visitor.visit_seq(&mut seq)?;
|
||||
seq.skip_remainder()?;
|
||||
|
@ -234,11 +265,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
|
|||
|
||||
fn deserialize_struct<V>(self,
|
||||
name: &'static str,
|
||||
fields: &'static [&'static str],
|
||||
_fields: &'static [&'static str],
|
||||
visitor: V)
|
||||
-> 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 result = visitor.visit_seq(&mut seq)?;
|
||||
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,
|
||||
i: B::Item,
|
||||
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 {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 Variant = Seq<'de, 'r, 'a, R>;
|
||||
|
||||
fn variant_seed<V>(self, seed: V)
|
||||
-> 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)?;
|
||||
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;
|
||||
|
||||
fn unit_variant(mut self) -> Result<()> {
|
||||
|
|
|
@ -11,15 +11,7 @@ pub enum Error {
|
|||
CannotDeserializeAny,
|
||||
MissingCloseDelimiter,
|
||||
MissingItem,
|
||||
Expected(ExpectedKind, Received),
|
||||
StreamingSerializationUnsupported,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Received {
|
||||
ReceivedSomethingElse,
|
||||
ReceivedRecordWithLabel(String),
|
||||
ReceivedOtherValue(String),
|
||||
Expected(ExpectedKind),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -35,16 +27,14 @@ pub enum ExpectedKind {
|
|||
ByteString,
|
||||
Symbol,
|
||||
|
||||
Record(Option<usize>),
|
||||
SimpleRecord(String, Option<usize>),
|
||||
Record,
|
||||
SimpleRecord(String),
|
||||
Sequence,
|
||||
Set,
|
||||
Dictionary,
|
||||
|
||||
Embedded,
|
||||
|
||||
SequenceOrSet, // Because of hacking up serde's data model: see open_sequence_or_set etc.
|
||||
|
||||
Option,
|
||||
UnicodeScalar,
|
||||
}
|
||||
|
|
|
@ -32,7 +32,10 @@ mod dom {
|
|||
Value::from(2).wrap()])
|
||||
.wrap();
|
||||
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() {
|
||||
|
@ -41,7 +44,10 @@ mod dom {
|
|||
Value::from(2).wrap()])
|
||||
.wrap();
|
||||
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)]
|
||||
mod decoder_tests {
|
||||
use crate::value::{Value, NestedValue, BinarySource, BytesBinarySource, ConfiguredReader};
|
||||
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>) {
|
||||
match r {
|
||||
|
@ -239,15 +251,15 @@ mod decoder_tests {
|
|||
fn expect_expected<T: core::fmt::Debug>(k: ExpectedKind, r: Result<T, Error>) {
|
||||
match r {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
#[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 d = ConfiguredReader::new(src.packed_iovalues());
|
||||
let mut d = src.packed().iovalues();
|
||||
let v = d.demand_next().unwrap();
|
||||
assert_eq!(v.annotations().slice().len(), 1);
|
||||
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
|
||||
|
@ -255,9 +267,9 @@ mod decoder_tests {
|
|||
}
|
||||
|
||||
#[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 d = ConfiguredReader::new(src.packed_iovalues());
|
||||
let mut d = src.packed().iovalues();
|
||||
d.set_read_annotations(false);
|
||||
let v = d.demand_next().unwrap();
|
||||
assert_eq!(v.annotations().slice().len(), 0);
|
||||
|
@ -265,37 +277,38 @@ mod decoder_tests {
|
|||
}
|
||||
|
||||
#[test] fn multiple_values_buf_advanced() {
|
||||
let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
|
||||
assert_eq!(buf.len(), 16);
|
||||
let buf = &b"\xa8\x87\xa7\x85\xa6Ping\x87\xa7\x85\xa6Pong"[..];
|
||||
assert_eq!(buf.len(), 17);
|
||||
let mut src = BytesBinarySource::new(&buf);
|
||||
let mut d = ConfiguredReader::new(src.packed_iovalues());
|
||||
assert_eq!(d.reader.source.index, 0);
|
||||
let mut d = src.packed().iovalues();
|
||||
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.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.reader.source.index, 16);
|
||||
assert_eq!(d.reader.source.source.index, 17);
|
||||
assert!(d.next().is_none());
|
||||
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_zero() { assert_eq!(from_bytes::<i8>(b"\x90").unwrap(), 0) }
|
||||
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\x9f").unwrap(), -1) }
|
||||
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa0\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_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_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"\xa3\x00").unwrap(), 0) }
|
||||
#[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"\xa3\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"\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_zero() { assert_eq!(from_bytes::<u8>(b"\x90").unwrap(), 0) }
|
||||
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa01").unwrap(), 49) }
|
||||
#[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"\xa3\x00").unwrap(), 0) }
|
||||
#[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_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_b() { assert_eq!(from_bytes::<i16>(b"\xa1\xfe\xff").unwrap(), -257) }
|
||||
#[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"\xa3\xfe\xff").unwrap(), -257) }
|
||||
|
||||
#[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() {
|
||||
|
@ -303,15 +316,15 @@ mod decoder_tests {
|
|||
}
|
||||
|
||||
#[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() {
|
||||
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() {
|
||||
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() {
|
||||
|
@ -319,50 +332,50 @@ mod decoder_tests {
|
|||
}
|
||||
|
||||
#[test] fn direct_i64_format_b() {
|
||||
assert_eq!(from_bytes::<i64>(b"\xa0\xff").unwrap(), -1);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa2\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"\xa0\xfe").unwrap(), -2);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa2\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"\xa9\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"\xa8\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"\xa9\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"\xa7\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"\xa7\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"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\xff").unwrap(), -1);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\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"\xa3\xfe").unwrap(), -2);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\xff\xfe\xff").unwrap(), -257);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\xfe\xff\xff").unwrap(), -65537);
|
||||
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"\xa3\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
|
||||
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"\xa3\xff\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"\xa3\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\0\0\0\0\0\0\0\0").unwrap(), 0);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3").unwrap(), 0);
|
||||
assert_eq!(from_bytes::<i64>(b"\xa3\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
||||
}
|
||||
|
||||
#[test] fn direct_u64_format_b() {
|
||||
expect_number_out_of_range(from_bytes::<u64>(b"\xa0\xff"));
|
||||
assert_eq!(from_bytes::<u64>(b"\xa1\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"));
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff").unwrap(), 255);
|
||||
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);
|
||||
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\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"\xa2\x00\x01\x00").unwrap(), 256);
|
||||
assert_eq!(from_bytes::<u64>(b"\xa2\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"\xa9\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"\xa9\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"));
|
||||
assert_eq!(from_bytes::<u64>(b"\xa8\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"\xa9\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"\xa7\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"));
|
||||
assert_eq!(from_bytes::<u64>(b"\xa8\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"\x90").unwrap(), 0);
|
||||
assert_eq!(from_bytes::<u64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
||||
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"\xa3\x02").unwrap(), 2);
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3\x00\x01\x00").unwrap(), 256);
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3\x01\x00\x00").unwrap(), 65536);
|
||||
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"\xa3\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
|
||||
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"\xa3\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
|
||||
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"\xa3\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
|
||||
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"\xa3\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
|
||||
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"\xa3\x80\0\0\0\0\0\0\0"));
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3\0\0\0\0\0\0\0\0").unwrap(), 0);
|
||||
assert_eq!(from_bytes::<u64>(b"\xa3").unwrap(), 0);
|
||||
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::de::from_bytes as deserialize_from_bytes;
|
||||
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::packed::PackedWriter;
|
||||
|
||||
|
@ -426,51 +439,51 @@ mod serde_tests {
|
|||
assert_eq!(v, x);
|
||||
|
||||
let expected_bytes = vec![
|
||||
0xb4, // Struct
|
||||
0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
|
||||
0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
|
||||
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1
|
||||
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2
|
||||
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3
|
||||
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4
|
||||
0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
|
||||
0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
|
||||
0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec"
|
||||
0xb5, // Sequence
|
||||
0x80, // false
|
||||
0x81, // true
|
||||
0x80, // false
|
||||
0x81, // true
|
||||
0x84,
|
||||
0xb6, // Set
|
||||
0xb1, 0x03, 0x6f, 0x6e, 0x65,
|
||||
0xb1, 0x03, 0x74, 0x77, 0x6f,
|
||||
0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65,
|
||||
0x84,
|
||||
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,
|
||||
0xa7, // Record
|
||||
0x8c, 0xa6, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
|
||||
0x87, 0xa4, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, // "hello"
|
||||
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x31, // sym1
|
||||
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x32, // sym2
|
||||
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x33, // sym3
|
||||
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x34, // sym4
|
||||
0x87, 0xa4, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x00, // "world"
|
||||
0x86, 0xa5, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
|
||||
0x84, 0xa5, 0x76, 0x65, 0x63, // #"vec"
|
||||
0x89, 0xa8, // Sequence
|
||||
0x81, 0xa0, // #f
|
||||
0x81, 0xa1, // #t
|
||||
0x81, 0xa0, // #f
|
||||
0x81, 0xa1, // #t
|
||||
0x95, 0xa9, // Set
|
||||
0x85, 0xa4, 0x6f, 0x6e, 0x65, 0x00, // "one"
|
||||
0x87, 0xa4, 0x74, 0x68, 0x72, 0x65, 0x65, 0x00, // "three"
|
||||
0x85, 0xa4, 0x74, 0x77, 0x6f, 0x00, // "two"
|
||||
0x83, 0xa3, 0x30, 0x39, // 12345
|
||||
0x84, 0xa4, 0x68, 0x69, 0x00, // "hi"
|
||||
|
||||
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
|
||||
0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
|
||||
0x84,
|
||||
0xcc, 0xaa, // Dictionary
|
||||
0x86, 0xa4, 0x62, 0x6c, 0x75, 0x65, 0x00, // "blue"
|
||||
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();
|
||||
println!("== w 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();
|
||||
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
|
||||
println!("== v bytes = {:?}", v_bytes_2);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use serde::Serialize;
|
||||
use super::value::IOValueDomainCodec;
|
||||
use super::value::boundary as B;
|
||||
use super::value::writer::{Writer, CompoundWriter};
|
||||
use super::value::writer::Writer;
|
||||
|
||||
pub use super::error::Error;
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -17,22 +17,21 @@ impl<'w, W: Writer> Serializer<'w, W> {
|
|||
}
|
||||
}
|
||||
|
||||
enum SequenceVariant<W: Writer> {
|
||||
Sequence(W::SeqWriter),
|
||||
Record(W::RecWriter),
|
||||
enum SequenceVariant {
|
||||
Sequence,
|
||||
Record,
|
||||
}
|
||||
|
||||
pub struct SerializeCompound<'a, 'w, W: Writer> {
|
||||
b: B::Type,
|
||||
i: B::Item,
|
||||
ser: &'a mut Serializer<'w, W>,
|
||||
c: SequenceVariant<W>,
|
||||
variant: SequenceVariant,
|
||||
}
|
||||
|
||||
pub struct SerializeDictionary<'a, 'w, W: Writer> {
|
||||
b: B::Type,
|
||||
ser: &'a mut Serializer<'w, W>,
|
||||
d: W::DictWriter,
|
||||
}
|
||||
|
||||
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> {
|
||||
let mut c = self.write.start_record(Some(1))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol("UnicodeScalar")?;
|
||||
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
c.write_u32(v as u32)?;
|
||||
c.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol("UnicodeScalar")?;
|
||||
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
self.write.write_u32(v as u32)?;
|
||||
self.write.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
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> {
|
||||
let mut c = self.write.start_record(Some(0))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol("None")?;
|
||||
c.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol("None")?;
|
||||
self.write.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
|
||||
let mut c = self.write.start_record(Some(1))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol("Some")?;
|
||||
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
to_writer(&mut c, v)?;
|
||||
c.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol("Some")?;
|
||||
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
to_writer(self.write, v)?;
|
||||
self.write.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok> {
|
||||
let mut c = self.write.start_record(Some(0))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol("tuple")?;
|
||||
c.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol("tuple")?;
|
||||
self.write.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
|
||||
let mut c = self.write.start_record(Some(0))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(name)?;
|
||||
c.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(name)?;
|
||||
self.write.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
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) ->
|
||||
Result<Self::Ok>
|
||||
{
|
||||
let mut c = self.write.start_record(Some(0))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(variant_name)?;
|
||||
c.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(variant_name)?;
|
||||
self.write.boundary(&B::end(B::Item::RecordLabel))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
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)?),
|
||||
None => {
|
||||
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
|
||||
let mut c = self.write.start_record(Some(1))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(name)?;
|
||||
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
to_writer(&mut c, value)?;
|
||||
c.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(name)?;
|
||||
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
to_writer(self.write, value)?;
|
||||
self.write.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,72 +179,72 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
|
|||
value: &T) ->
|
||||
Result<Self::Ok> where T: Serialize
|
||||
{
|
||||
let mut c = self.write.start_record(Some(1))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(variant_name)?;
|
||||
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
to_writer(&mut c, value)?;
|
||||
c.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record(c)?)
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(variant_name)?;
|
||||
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
|
||||
to_writer(self.write, value)?;
|
||||
self.write.boundary(&B::end(B::Item::RecordField))?;
|
||||
Ok(self.write.end_record()?)
|
||||
}
|
||||
|
||||
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||
let c = self.write.start_sequence(count)?;
|
||||
Ok(SerializeCompound::seq(self, c))
|
||||
fn serialize_seq(self, _count: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||
self.write.start_sequence()?;
|
||||
Ok(SerializeCompound::seq(self))
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
|
||||
let mut c = self.write.start_record(Some(count))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol("tuple")?;
|
||||
Ok(SerializeCompound::rec(self, c))
|
||||
fn serialize_tuple(self, _count: usize) -> Result<Self::SerializeTuple> {
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol("tuple")?;
|
||||
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>
|
||||
{
|
||||
let mut c = self.write.start_record(Some(count))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(name)?;
|
||||
Ok(SerializeCompound::rec(self, c))
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(name)?;
|
||||
Ok(SerializeCompound::rec(self))
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(self,
|
||||
_name: &'static str,
|
||||
_variant: u32,
|
||||
variant_name: &'static str,
|
||||
count: usize) ->
|
||||
_count: usize) ->
|
||||
Result<Self::SerializeTupleVariant>
|
||||
{
|
||||
let mut c = self.write.start_record(Some(count))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(variant_name)?;
|
||||
Ok(SerializeCompound::rec(self, c))
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(variant_name)?;
|
||||
Ok(SerializeCompound::rec(self))
|
||||
}
|
||||
|
||||
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
|
||||
let d = self.write.start_dictionary(count)?;
|
||||
Ok(SerializeDictionary { b: B::Type::default(), ser: self, d })
|
||||
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
|
||||
self.write.start_dictionary()?;
|
||||
Ok(SerializeDictionary { b: B::Type::default(), ser: self })
|
||||
}
|
||||
|
||||
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
|
||||
let mut c = self.write.start_record(Some(count))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(name)?;
|
||||
Ok(SerializeCompound::rec(self, c))
|
||||
fn serialize_struct(self, name: &'static str, _count: usize) -> Result<Self::SerializeStruct> {
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(name)?;
|
||||
Ok(SerializeCompound::rec(self))
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(self,
|
||||
_name: &'static str,
|
||||
_variant: u32,
|
||||
variant_name: &'static str,
|
||||
count: usize) ->
|
||||
_count: usize) ->
|
||||
Result<Self::SerializeStructVariant>
|
||||
{
|
||||
let mut c = self.write.start_record(Some(count))?;
|
||||
c.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
c.write_symbol(variant_name)?;
|
||||
Ok(SerializeCompound::rec(self, c))
|
||||
self.write.start_record()?;
|
||||
self.write.boundary(&B::start(B::Item::RecordLabel))?;
|
||||
self.write.write_symbol(variant_name)?;
|
||||
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 {
|
||||
self.b.opening = Some(B::Item::DictionaryKey);
|
||||
self.d.boundary(&self.b)?;
|
||||
to_writer(&mut self.d, key)?;
|
||||
self.ser.write.boundary(&self.b)?;
|
||||
to_writer(self.ser.write, key)?;
|
||||
self.b.shift(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
||||
self.b.opening = Some(B::Item::DictionaryValue);
|
||||
self.d.boundary(&self.b)?;
|
||||
to_writer(&mut self.d, value)?;
|
||||
self.ser.write.boundary(&self.b)?;
|
||||
to_writer(self.ser.write, value)?;
|
||||
self.b.shift(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(mut self) -> Result<Self::Ok> {
|
||||
self.d.boundary(&self.b)?;
|
||||
Ok(self.ser.write.end_dictionary(self.d)?)
|
||||
fn end(self) -> Result<Self::Ok> {
|
||||
self.ser.write.boundary(&self.b)?;
|
||||
Ok(self.ser.write.end_dictionary()?)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
b: B::Type::default(),
|
||||
i: B::Item::SequenceValue,
|
||||
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 {
|
||||
b: B::end(B::Item::RecordLabel),
|
||||
i: B::Item::RecordField,
|
||||
ser,
|
||||
c: SequenceVariant::Record(c),
|
||||
variant: SequenceVariant::Record,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,23 +297,21 @@ impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
|
|||
where T: Serialize
|
||||
{
|
||||
self.b.opening = Some(self.i.clone());
|
||||
match &mut self.c {
|
||||
SequenceVariant::Sequence(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
|
||||
SequenceVariant::Record(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
|
||||
}
|
||||
self.ser.write.boundary(&self.b)?;
|
||||
to_writer(self.ser.write, value)?;
|
||||
self.b.shift(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn complete(self) -> Result<()> {
|
||||
match self.c {
|
||||
SequenceVariant::Sequence(mut w) => {
|
||||
w.boundary(&self.b)?;
|
||||
Ok(self.ser.write.end_sequence(w)?)
|
||||
match self.variant {
|
||||
SequenceVariant::Sequence => {
|
||||
self.ser.write.boundary(&self.b)?;
|
||||
Ok(self.ser.write.end_sequence()?)
|
||||
}
|
||||
SequenceVariant::Record(mut w) => {
|
||||
w.boundary(&self.b)?;
|
||||
Ok(self.ser.write.end_record(w)?)
|
||||
SequenceVariant::Record => {
|
||||
self.ser.write.boundary(&self.b)?;
|
||||
Ok(self.ser.write.end_record()?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::value::repr::{Float, Double};
|
||||
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map};
|
||||
use crate::error::{Error, ExpectedKind, Received};
|
||||
use crate::value::{Value, NestedValue, IOValue, Map};
|
||||
use crate::error::Error;
|
||||
use serde::Deserialize;
|
||||
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
|
||||
use std::iter::Iterator;
|
||||
|
@ -11,7 +11,7 @@ pub struct Deserializer<'de> {
|
|||
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 t = T::deserialize(&mut de)?;
|
||||
|
@ -22,13 +22,6 @@ impl<'de> Deserializer<'de> {
|
|||
pub fn from_value(v: &'de IOValue) -> Self {
|
||||
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>
|
||||
|
@ -42,7 +35,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
|
|||
Value::Boolean(b) => visitor.visit_bool(*b),
|
||||
Value::Float(Float(f)) => visitor.visit_f32(*f),
|
||||
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::Record(_) =>
|
||||
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>
|
||||
{
|
||||
let s: &'de str = &self.input.value().to_string()?;
|
||||
visitor.visit_borrowed_str(s)
|
||||
visitor.visit_borrowed_str(self.input.value().to_string()?)
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
let bs: &'de [u8] = &self.input.value().to_bytestring()?;
|
||||
visitor.visit_borrowed_bytes(bs)
|
||||
visitor.visit_borrowed_bytes(self.input.value().to_bytestring()?)
|
||||
}
|
||||
|
||||
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> {
|
||||
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)
|
||||
-> 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;
|
||||
self.input = r.label();
|
||||
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> {
|
||||
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];
|
||||
seed.deserialize(&mut *self)
|
||||
}
|
||||
|
|
|
@ -1,24 +1,14 @@
|
|||
use std::io;
|
||||
|
||||
use super::BinarySource;
|
||||
use super::BytesBinarySource;
|
||||
use super::Embeddable;
|
||||
use super::IOValue;
|
||||
use super::Reader;
|
||||
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> {
|
||||
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
|
||||
fn decode_embedded<'de, 'r, R: Reader<'de>>(
|
||||
&mut self,
|
||||
src: &'src mut S,
|
||||
r: &'r mut R,
|
||||
read_annotations: bool,
|
||||
) -> io::Result<D>;
|
||||
}
|
||||
|
@ -31,34 +21,15 @@ pub trait DomainEncode<D: Embeddable> {
|
|||
) -> 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;
|
||||
|
||||
impl DomainDecode<IOValue> for IOValueDomainCodec {
|
||||
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
|
||||
fn decode_embedded<'de, 'r, R: Reader<'de>>(
|
||||
&mut self,
|
||||
src: &'src mut S,
|
||||
r: &'r mut R,
|
||||
read_annotations: bool,
|
||||
) -> 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;
|
||||
|
||||
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,
|
||||
_src: &'src mut S,
|
||||
_r: &'r mut R,
|
||||
_read_annotations: bool,
|
||||
) -> io::Result<D> {
|
||||
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"))
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
pub mod boundary;
|
||||
pub mod de;
|
||||
pub mod domain;
|
||||
pub mod iolist;
|
||||
pub mod magic;
|
||||
pub mod packed;
|
||||
pub mod reader;
|
||||
pub mod repr;
|
||||
pub mod ser;
|
||||
pub mod signed_integer;
|
||||
pub mod source;
|
||||
pub mod suspendable;
|
||||
pub mod text;
|
||||
pub mod writer;
|
||||
|
@ -16,17 +18,12 @@ pub use de::Deserializer;
|
|||
pub use de::from_value;
|
||||
pub use domain::DomainDecode;
|
||||
pub use domain::DomainEncode;
|
||||
pub use domain::DomainParse;
|
||||
pub use domain::IOValueDomainCodec;
|
||||
pub use domain::NoEmbeddedDomainCodec;
|
||||
pub use domain::ViaCodec;
|
||||
pub use merge::merge;
|
||||
pub use packed::PackedReader;
|
||||
pub use packed::PackedWriter;
|
||||
pub use reader::BinarySource;
|
||||
pub use reader::BytesBinarySource;
|
||||
pub use reader::ConfiguredReader;
|
||||
pub use reader::IOBinarySource;
|
||||
pub use reader::Reader;
|
||||
pub use reader::Token;
|
||||
pub use repr::AnnotatedValue;
|
||||
|
@ -50,6 +47,9 @@ pub use repr::Value;
|
|||
pub use repr::ValueClass;
|
||||
pub use ser::Serializer;
|
||||
pub use ser::to_value;
|
||||
pub use source::BinarySource;
|
||||
pub use source::BytesBinarySource;
|
||||
pub use source::IOBinarySource;
|
||||
pub use text::TextReader;
|
||||
pub use text::TextWriter;
|
||||
pub use writer::Writer;
|
||||
|
|
|
@ -6,12 +6,6 @@ pub enum Tag {
|
|||
False,
|
||||
True,
|
||||
Float,
|
||||
Double,
|
||||
End,
|
||||
Annotation,
|
||||
Embedded,
|
||||
SmallInteger(i8),
|
||||
MediumInteger(u8),
|
||||
SignedInteger,
|
||||
String,
|
||||
ByteString,
|
||||
|
@ -20,6 +14,8 @@ pub enum Tag {
|
|||
Sequence,
|
||||
Set,
|
||||
Dictionary,
|
||||
Embedded,
|
||||
Annotation,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -41,24 +37,19 @@ impl TryFrom<u8> for Tag {
|
|||
type Error = InvalidTag;
|
||||
fn try_from(v: u8) -> Result<Self, Self::Error> {
|
||||
match v {
|
||||
0x80 => Ok(Self::False),
|
||||
0x81 => Ok(Self::True),
|
||||
0x82 => Ok(Self::Float),
|
||||
0x83 => Ok(Self::Double),
|
||||
0x84 => Ok(Self::End),
|
||||
0x85 => Ok(Self::Annotation),
|
||||
0x86 => Ok(Self::Embedded),
|
||||
0x90..=0x9c => Ok(Self::SmallInteger((v - 0x90) as i8)),
|
||||
0x9d..=0x9f => Ok(Self::SmallInteger((v - 0x90) as i8 - 16)),
|
||||
0xa0..=0xaf => Ok(Self::MediumInteger(v - 0xa0 + 1)),
|
||||
0xb0 => Ok(Self::SignedInteger),
|
||||
0xb1 => Ok(Self::String),
|
||||
0xb2 => Ok(Self::ByteString),
|
||||
0xb3 => Ok(Self::Symbol),
|
||||
0xb4 => Ok(Self::Record),
|
||||
0xb5 => Ok(Self::Sequence),
|
||||
0xb6 => Ok(Self::Set),
|
||||
0xb7 => Ok(Self::Dictionary),
|
||||
0xa0 => Ok(Self::False),
|
||||
0xa1 => Ok(Self::True),
|
||||
0xa2 => Ok(Self::Float),
|
||||
0xa3 => Ok(Self::SignedInteger),
|
||||
0xa4 => Ok(Self::String),
|
||||
0xa5 => Ok(Self::ByteString),
|
||||
0xa6 => Ok(Self::Symbol),
|
||||
0xa7 => Ok(Self::Record),
|
||||
0xa8 => Ok(Self::Sequence),
|
||||
0xa9 => Ok(Self::Set),
|
||||
0xaa => Ok(Self::Dictionary),
|
||||
0xab => Ok(Self::Embedded),
|
||||
0xbf => Ok(Self::Annotation),
|
||||
_ => Err(InvalidTag(v))
|
||||
}
|
||||
}
|
||||
|
@ -67,23 +58,19 @@ impl TryFrom<u8> for Tag {
|
|||
impl From<Tag> for u8 {
|
||||
fn from(v: Tag) -> Self {
|
||||
match v {
|
||||
Tag::False => 0x80,
|
||||
Tag::True => 0x81,
|
||||
Tag::Float => 0x82,
|
||||
Tag::Double => 0x83,
|
||||
Tag::End => 0x84,
|
||||
Tag::Annotation => 0x85,
|
||||
Tag::Embedded => 0x86,
|
||||
Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 },
|
||||
Tag::MediumInteger(count) => count - 1 + 0xa0,
|
||||
Tag::SignedInteger => 0xb0,
|
||||
Tag::String => 0xb1,
|
||||
Tag::ByteString => 0xb2,
|
||||
Tag::Symbol => 0xb3,
|
||||
Tag::Record => 0xb4,
|
||||
Tag::Sequence => 0xb5,
|
||||
Tag::Set => 0xb6,
|
||||
Tag::Dictionary => 0xb7,
|
||||
Tag::False => 0xa0,
|
||||
Tag::True => 0xa1,
|
||||
Tag::Float => 0xa2,
|
||||
Tag::SignedInteger => 0xa3,
|
||||
Tag::String => 0xa4,
|
||||
Tag::ByteString => 0xa5,
|
||||
Tag::Symbol => 0xa6,
|
||||
Tag::Record => 0xa7,
|
||||
Tag::Sequence => 0xa8,
|
||||
Tag::Set => 0xa9,
|
||||
Tag::Dictionary => 0xaa,
|
||||
Tag::Embedded => 0xab,
|
||||
Tag::Annotation => 0xbf,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,22 +11,22 @@ use super::{BinarySource, DomainDecode, IOValue, IOValueDomainCodec, NestedValue
|
|||
|
||||
pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
bs: &[u8],
|
||||
decode_embedded: Dec,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> 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> {
|
||||
from_bytes(bs, IOValueDomainCodec)
|
||||
from_bytes(bs, &mut IOValueDomainCodec)
|
||||
}
|
||||
|
||||
pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
bs: &[u8],
|
||||
decode_embedded: Dec,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> 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> {
|
||||
annotated_from_bytes(bs, IOValueDomainCodec)
|
||||
annotated_from_bytes(bs, &mut IOValueDomainCodec)
|
||||
}
|
||||
|
|
|
@ -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::traits::cast::{FromPrimitive, ToPrimitive};
|
||||
|
@ -6,6 +6,7 @@ use num::traits::cast::{FromPrimitive, ToPrimitive};
|
|||
use std::borrow::Cow;
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Debug;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
@ -15,6 +16,7 @@ use super::super::{
|
|||
DomainDecode,
|
||||
Map,
|
||||
NestedValue,
|
||||
NoEmbeddedDomainCodec,
|
||||
Record,
|
||||
Set,
|
||||
Value,
|
||||
|
@ -22,116 +24,294 @@ use super::super::{
|
|||
boundary as B,
|
||||
reader::{
|
||||
Token,
|
||||
BinarySource,
|
||||
Reader,
|
||||
ReaderResult,
|
||||
},
|
||||
repr::Annotations,
|
||||
signed_integer::SignedInteger,
|
||||
source::BinarySource,
|
||||
};
|
||||
|
||||
pub struct PackedReader<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> {
|
||||
pub source: &'src mut S,
|
||||
pub decode_embedded: Dec,
|
||||
phantom: PhantomData<&'de N>,
|
||||
#[derive(Debug)]
|
||||
enum Continuation {
|
||||
Skip { count: Option<u64> },
|
||||
Sequence { count: Option<u64> },
|
||||
}
|
||||
|
||||
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
|
||||
BinarySource<'de>
|
||||
for PackedReader<'de, 'src, N, Dec, S>
|
||||
{
|
||||
type Mark = S::Mark;
|
||||
pub struct PackedReaderSource<'de, 'src, S: BinarySource<'de>> {
|
||||
pub source: &'src mut S,
|
||||
stack: Vec<Continuation>,
|
||||
count: Option<u64>,
|
||||
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)]
|
||||
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)]
|
||||
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)]
|
||||
fn skip(&mut self) -> io::Result<()> {
|
||||
self.advance_or_eof(1)?;
|
||||
self.source.skip()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn peek(&mut self) -> io::Result<u8> {
|
||||
self.source.peek()
|
||||
fn peek(&mut self) -> io::Result<Option<u8>> {
|
||||
match self.count {
|
||||
Some(0) => Ok(None),
|
||||
_ => self.source.peek(),
|
||||
}
|
||||
}
|
||||
|
||||
#[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)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
|
||||
self.advance_or_eof(bs.len() as u64)?;
|
||||
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 {
|
||||
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)]
|
||||
pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self {
|
||||
PackedReader { source, decode_embedded, phantom: PhantomData }
|
||||
pub fn new(source: &'src mut S) -> Self {
|
||||
PackedReader {
|
||||
source: PackedReaderSource {
|
||||
source,
|
||||
stack: Vec::new(),
|
||||
count: None,
|
||||
expect_length: false,
|
||||
phantom: PhantomData,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read(&mut self) -> io::Result<u8> {
|
||||
let v = self.peek()?;
|
||||
self.skip()?;
|
||||
Ok(v)
|
||||
fn peek_tag(&mut self) -> io::Result<Tag> {
|
||||
Ok(Tag::try_from(self.source.peek_noeof()?)?)
|
||||
}
|
||||
|
||||
#[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 {
|
||||
match self.demand_next(true) {
|
||||
Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
|
||||
Err(e) => e.into()
|
||||
}
|
||||
error::Error::Expected(k)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn varint(&mut self) -> io::Result<usize> {
|
||||
let mut shift = 0;
|
||||
let mut acc: usize = 0;
|
||||
fn next_nonannotation_tag(&mut self) -> io::Result<Tag> {
|
||||
self.source.narrow()?;
|
||||
loop {
|
||||
let v = self.read()?;
|
||||
acc |= ((v & 0x7f) as usize) << shift;
|
||||
shift += 7;
|
||||
if v & 0x80 == 0 { return Ok(acc) }
|
||||
}
|
||||
}
|
||||
|
||||
#[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),
|
||||
let tag = self.read_tag()?;
|
||||
if tag == Tag::Annotation {
|
||||
self.source.narrow_to_annotated_value()?;
|
||||
} else {
|
||||
return Ok(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> {
|
||||
let actual_tag = self.peek_next_nonannotation_tag()?;
|
||||
if actual_tag == expected_tag {
|
||||
self.skip()?;
|
||||
let count = self.varint()?;
|
||||
Ok(self.readbytes(count)?)
|
||||
if self.next_nonannotation_tag()? == expected_tag {
|
||||
let bs = self.source.read_to_end()?;
|
||||
Ok(self.source.widen(bs)?)
|
||||
} else {
|
||||
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<()>
|
||||
{
|
||||
let actual_tag = self.peek_next_nonannotation_tag()?;
|
||||
if actual_tag == expected_tag {
|
||||
self.skip()?;
|
||||
if self.next_nonannotation_tag()? == expected_tag {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(self.expected(k))
|
||||
|
@ -149,246 +327,136 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read_signed_integer(&mut self, count: usize) -> io::Result<SignedInteger> {
|
||||
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>
|
||||
fn next_unsigned<T: FromPrimitive + Debug, F>(&mut self, f: F) -> ReaderResult<T>
|
||||
where
|
||||
F: FnOnce(u128) -> Option<T>
|
||||
{
|
||||
let tag = self.peek_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))
|
||||
}
|
||||
match self.next_nonannotation_tag()? {
|
||||
Tag::SignedInteger => {
|
||||
self.skip()?;
|
||||
let count = self.varint()?;
|
||||
let n = &self.read_signed_integer(count)?;
|
||||
let n = &self.source.read_signed_integer()?;
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
#[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
|
||||
F: FnOnce(i128) -> Option<T>
|
||||
{
|
||||
let tag = self.peek_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))
|
||||
}
|
||||
match self.next_nonannotation_tag()? {
|
||||
Tag::SignedInteger => {
|
||||
self.skip()?;
|
||||
let count = self.varint()?;
|
||||
let n = &self.read_signed_integer(count)?;
|
||||
let n = &self.source.read_signed_integer()?;
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_annotations(&mut self) -> io::Result<Vec<N>> {
|
||||
let mut annotations = vec![self.demand_next(true)?];
|
||||
while Tag::try_from(self.peek()?)? == Tag::Annotation {
|
||||
self.skip()?;
|
||||
annotations.push(self.demand_next(true)?);
|
||||
}
|
||||
Ok(annotations)
|
||||
}
|
||||
|
||||
fn skip_annotations(&mut self) -> io::Result<()> {
|
||||
self.skip_value()?;
|
||||
while Tag::try_from(self.peek()?)? == Tag::Annotation {
|
||||
self.skip()?;
|
||||
self.skip_value()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn next_upto_end(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
|
||||
match self.peekend()? {
|
||||
true => Ok(None),
|
||||
false => Ok(Some(self.demand_next(read_annotations)?)),
|
||||
fn _next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<N> {
|
||||
loop {
|
||||
return Ok(match self.read_tag()? {
|
||||
Tag::False => N::new(false),
|
||||
Tag::True => N::new(true),
|
||||
Tag::Float => {
|
||||
let bs = self.source.read_to_end()?;
|
||||
match bs.len() {
|
||||
4 => Value::from(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap()))).wrap(),
|
||||
8 => Value::from(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap()))).wrap(),
|
||||
_ => Err(io_syntax_error("Invalid floating-point width"))?,
|
||||
}
|
||||
}
|
||||
Tag::SignedInteger => Value::SignedInteger(self.source.read_signed_integer()?).wrap(),
|
||||
Tag::String => Value::String(decode_nul_str(self.source.read_to_end()?)?.into_owned()).wrap(),
|
||||
Tag::ByteString => Value::ByteString(self.source.read_to_end()?.into_owned()).wrap(),
|
||||
Tag::Symbol => Value::Symbol(decodestr(self.source.read_to_end()?)?.into_owned()).wrap(),
|
||||
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>>
|
||||
Reader<'de, N>
|
||||
for PackedReader<'de, 'src, N, Dec, S>
|
||||
{
|
||||
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
|
||||
match self.peek() {
|
||||
Err(e) if is_eof_io_error(&e) => return Ok(None),
|
||||
Err(e) => return Err(e),
|
||||
Ok(_) => (),
|
||||
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S> {
|
||||
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Option<N>> {
|
||||
match self.source.peek()? {
|
||||
None => Ok(None),
|
||||
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)]
|
||||
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
|
||||
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
|
||||
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)),
|
||||
}
|
||||
fn open_record(&mut self) -> ReaderResult<()> {
|
||||
self.next_compound(Tag::Record, ExpectedKind::Record)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -413,7 +481,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
|
||||
#[inline(always)]
|
||||
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)]
|
||||
|
@ -423,95 +495,82 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
|
||||
#[inline(always)]
|
||||
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)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
self.source.mark()
|
||||
BinarySource::mark(&mut self.source)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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>> {
|
||||
loop {
|
||||
return Ok(match Tag::try_from(self.peek()?)? {
|
||||
Tag::Embedded => {
|
||||
self.skip()?;
|
||||
Token::Embedded(self.decode_embedded.decode_embedded(
|
||||
self.source,
|
||||
read_embedded_annotations)?)
|
||||
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_embedded_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Token<N>> {
|
||||
match self.source.peek()? {
|
||||
None => self.source.widen(Token::End),
|
||||
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)]
|
||||
fn next_boolean(&mut self) -> ReaderResult<bool> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::False => { self.skip()?; Ok(false) }
|
||||
Tag::True => { self.skip()?; Ok(true) }
|
||||
_ => Err(self.expected(ExpectedKind::Boolean)),
|
||||
match self.next_nonannotation_tag()? {
|
||||
Tag::False => { Ok(self.source.widen(false)?) }
|
||||
Tag::True => { Ok(self.source.widen(true)?) }
|
||||
_ => Err(self.expected(ExpectedKind::Boolean))?,
|
||||
}
|
||||
}
|
||||
|
||||
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
|
||||
let tag = self.peek_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())?)
|
||||
}
|
||||
match self.next_nonannotation_tag()? {
|
||||
Tag::SignedInteger => {
|
||||
self.skip()?;
|
||||
let count = self.varint()?;
|
||||
Ok(self.read_signed_integer(count)?)
|
||||
}
|
||||
_ => Err(self.expected(ExpectedKind::SignedInteger))
|
||||
let i = self.source.read_signed_integer()?;
|
||||
Ok(self.source.widen(i)?)
|
||||
},
|
||||
_ => 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_f32(&mut self) -> ReaderResult<f32> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::Float => {
|
||||
self.skip()?;
|
||||
let mut bs = [0; 4];
|
||||
self.readbytes_into(&mut bs)?;
|
||||
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)),
|
||||
let bs = self.next_atomic(Tag::Float, ExpectedKind::Float)?;
|
||||
match bs.len() {
|
||||
4 => Ok(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap()))),
|
||||
8 => Ok(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap())) as f32),
|
||||
_ => Err(io_syntax_error("Invalid floating-point width"))?,
|
||||
}
|
||||
}
|
||||
|
||||
fn next_f64(&mut self) -> ReaderResult<f64> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::Float => {
|
||||
self.skip()?;
|
||||
let mut bs = [0; 4];
|
||||
self.readbytes_into(&mut bs)?;
|
||||
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)),
|
||||
let bs = self.next_atomic(Tag::Float, ExpectedKind::Double)?;
|
||||
match bs.len() {
|
||||
4 => Ok(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap())) as f64),
|
||||
8 => Ok(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap()))),
|
||||
_ => Err(io_syntax_error("Invalid floating-point width"))?,
|
||||
}
|
||||
}
|
||||
|
||||
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]>> {
|
||||
self.next_atomic(Tag::ByteString, ExpectedKind::Symbol)
|
||||
self.next_atomic(Tag::ByteString, ExpectedKind::ByteString)
|
||||
}
|
||||
|
||||
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"))?)),
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
use num::bigint::BigInt;
|
||||
use num::cast::ToPrimitive;
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryInto;
|
||||
use std::io;
|
||||
use std::ops::DerefMut;
|
||||
use super::constants::Tag;
|
||||
use super::super::DomainEncode;
|
||||
use super::super::IOValue;
|
||||
use super::super::IOValueDomainCodec;
|
||||
use super::super::NestedValue;
|
||||
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>(Suspendable<W>);
|
||||
pub struct PackedWriter<W: io::Write> {
|
||||
w: W,
|
||||
buffer: IOList,
|
||||
items: Vec<Vec<IOList>>,
|
||||
}
|
||||
|
||||
impl PackedWriter<&mut Vec<u8>> {
|
||||
#[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> {
|
||||
#[inline(always)]
|
||||
pub fn new(write: W) -> Self {
|
||||
PackedWriter(Suspendable::new(write))
|
||||
PackedWriter {
|
||||
w: write,
|
||||
buffer: IOList::new(),
|
||||
items: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn w(&mut self) -> &mut W {
|
||||
self.0.deref_mut()
|
||||
pub fn write_byte(&mut self, b: u8) {
|
||||
self.buffer.write(b)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_byte(&mut self, b: u8) -> io::Result<()> {
|
||||
self.w().write_all(&[b])
|
||||
pub fn write_all(&mut self, bs: &[u8]) {
|
||||
self.buffer.write_all(Cow::Borrowed(bs))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> {
|
||||
let count: u8 = bs.len().try_into().unwrap();
|
||||
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) }
|
||||
self.write_byte(Tag::MediumInteger(count).into())?;
|
||||
self.w().write_all(bs)
|
||||
pub fn write_integer(&mut self, bs: &[u8]) -> io::Result<()> {
|
||||
self.write_atom(Tag::SignedInteger, bs)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_tag(&mut self, tag: Tag) {
|
||||
self.write_byte(tag.into())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> io::Result<()> {
|
||||
self.write_byte(tag.into())?;
|
||||
varint(&mut self.w(), bs.len().try_into().unwrap())?;
|
||||
self.w().write_all(bs)
|
||||
self.write_tag(tag);
|
||||
self.write_all(bs);
|
||||
self.finish_item_if_toplevel()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn suspend(&mut self) -> Self {
|
||||
PackedWriter(self.0.suspend())
|
||||
}
|
||||
|
||||
#[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)?;
|
||||
pub fn finish_item(&mut self) -> io::Result<()> {
|
||||
let buffer = std::mem::replace(&mut self.buffer, IOList::new());
|
||||
match self.items.last_mut() {
|
||||
Some(iols) => Ok(iols.push(buffer)),
|
||||
None => buffer.write_to(&mut self.w),
|
||||
}
|
||||
w.write_tag(Tag::End)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WriteWriter: Writer {
|
||||
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()>;
|
||||
|
||||
#[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)?;
|
||||
pub fn finish_item_if_toplevel(&mut self) -> io::Result<()> {
|
||||
if self.items.is_empty() {
|
||||
self.finish_item()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl CompoundWriter for BinaryOrderWriter {
|
||||
#[inline(always)]
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
|
||||
match b.closing {
|
||||
Some(B::Item::DictionaryValue) |
|
||||
Some(B::Item::RecordField) |
|
||||
Some(B::Item::SequenceValue) |
|
||||
Some(B::Item::SetValue) =>
|
||||
self.items_mut().push(vec![]),
|
||||
_ =>
|
||||
()
|
||||
pub fn start_seq(&mut self) -> io::Result<()> {
|
||||
self.items.push(Vec::new());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn finish_seq(&mut self, tag: Tag, sort: bool) -> io::Result<()> {
|
||||
let mut items = self.items.pop().unwrap();
|
||||
if sort {
|
||||
items.sort();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! binary_order_writer_method {
|
||||
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) =>
|
||||
(#[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(())
|
||||
self.write_tag(tag);
|
||||
for mut i in items {
|
||||
varint(&mut self.buffer, i.len());
|
||||
self.buffer.append(i);
|
||||
}
|
||||
self.finish_item_if_toplevel()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,162 +127,171 @@ macro_rules! fits_in_bytes {
|
|||
|
||||
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)]
|
||||
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
|
||||
Ok(self.suspend())
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
|
||||
match (b.closing.as_ref(), b.opening.as_ref()) {
|
||||
(Some(_), _) =>
|
||||
self.finish_item(),
|
||||
(None, _) =>
|
||||
Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
|
||||
self.resume(ann);
|
||||
Ok(())
|
||||
fn start_annotations(&mut self) -> io::Result<()> {
|
||||
self.start_seq()
|
||||
}
|
||||
|
||||
#[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)]
|
||||
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)]
|
||||
fn write_f32(&mut self, v: f32) -> io::Result<()> {
|
||||
self.write_tag(Tag::Float)?;
|
||||
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
|
||||
self.write_tag(Tag::Float);
|
||||
self.write_all(&u32::to_be_bytes(f32::to_bits(v)));
|
||||
self.finish_item_if_toplevel()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_f64(&mut self, v: f64) -> io::Result<()> {
|
||||
self.write_tag(Tag::Double)?;
|
||||
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
|
||||
self.write_tag(Tag::Float);
|
||||
self.write_all(&u64::to_be_bytes(f64::to_bits(v)));
|
||||
self.finish_item_if_toplevel()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i8(&mut self, v: i8) -> io::Result<()> {
|
||||
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
|
||||
self.write_medium_integer(&[v as u8])
|
||||
if v == 0 {
|
||||
self.write_integer(&[])
|
||||
} else {
|
||||
self.write_integer(&[v as u8])
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u8(&mut self, v: u8) -> io::Result<()> {
|
||||
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)]
|
||||
fn write_i16(&mut self, v: i16) -> io::Result<()> {
|
||||
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)]
|
||||
fn write_u16(&mut self, v: u16) -> io::Result<()> {
|
||||
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)]
|
||||
fn write_i32(&mut self, v: i32) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
||||
if fits_in_bytes!(v, 3) {
|
||||
return self.write_medium_integer(&[(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
return self.write_integer(&[(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
}
|
||||
self.write_medium_integer(&[(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
self.write_integer(&[(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u32(&mut self, v: u32) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||
self.write_medium_integer(&[0,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
self.write_integer(&[0,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i64(&mut self, v: i64) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||
if fits_in_bytes!(v, 5) {
|
||||
return self.write_medium_integer(&[(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
return self.write_integer(&[(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
}
|
||||
if fits_in_bytes!(v, 6) {
|
||||
return self.write_medium_integer(&[(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
return self.write_integer(&[(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
}
|
||||
if fits_in_bytes!(v, 7) {
|
||||
return self.write_medium_integer(&[(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
return self.write_integer(&[(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
}
|
||||
self.write_medium_integer(&[(v >> 56) as u8,
|
||||
(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
self.write_integer(&[(v >> 56) as u8,
|
||||
(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u64(&mut self, v: u64) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||
self.write_medium_integer(&[0,
|
||||
(v >> 56) as u8,
|
||||
(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
self.write_integer(&[0,
|
||||
(v >> 56) as u8,
|
||||
(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i128(&mut self, v: i128) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||
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, 10) { return self.write_medium_integer(&bs[6..]); }
|
||||
if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); }
|
||||
if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); }
|
||||
if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); }
|
||||
if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); }
|
||||
if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); }
|
||||
self.write_medium_integer(&bs)
|
||||
if fits_in_bytes!(v, 9) { return self.write_integer(&bs[7..]); }
|
||||
if fits_in_bytes!(v, 10) { return self.write_integer(&bs[6..]); }
|
||||
if fits_in_bytes!(v, 11) { return self.write_integer(&bs[5..]); }
|
||||
if fits_in_bytes!(v, 12) { return self.write_integer(&bs[4..]); }
|
||||
if fits_in_bytes!(v, 13) { return self.write_integer(&bs[3..]); }
|
||||
if fits_in_bytes!(v, 14) { return self.write_integer(&bs[2..]); }
|
||||
if fits_in_bytes!(v, 15) { return self.write_integer(&bs[1..]); }
|
||||
self.write_integer(&bs)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u128(&mut self, v: u128) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i128(w) }
|
||||
let bs: [u8; 16] = v.to_be_bytes();
|
||||
self.write_tag(Tag::SignedInteger)?;
|
||||
varint(&mut self.w(), 17)?;
|
||||
self.write_byte(0)?;
|
||||
self.write_raw_bytes(&bs)
|
||||
self.write_tag(Tag::SignedInteger);
|
||||
self.write_byte(0);
|
||||
self.write_all(&bs);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -457,7 +309,10 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
|
||||
#[inline(always)]
|
||||
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)]
|
||||
|
@ -471,65 +326,84 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
|
||||
self.write_tag(Tag::Record)?;
|
||||
Ok(self.suspend())
|
||||
fn start_record(&mut self) -> io::Result<()> {
|
||||
self.start_seq()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
|
||||
self.resume(rec);
|
||||
self.write_tag(Tag::End)
|
||||
fn end_record(&mut self) -> io::Result<()> {
|
||||
self.finish_seq(Tag::Record, false)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
|
||||
self.write_tag(Tag::Sequence)?;
|
||||
Ok(self.suspend())
|
||||
fn start_sequence(&mut self) -> io::Result<()> {
|
||||
self.start_seq()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
|
||||
self.resume(seq);
|
||||
self.write_tag(Tag::End)
|
||||
fn end_sequence(&mut self) -> io::Result<()> {
|
||||
self.finish_seq(Tag::Sequence, false)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
|
||||
self.write_tag(Tag::Set)?;
|
||||
Ok(BinaryOrderWriter::new())
|
||||
fn start_set(&mut self) -> io::Result<()> {
|
||||
self.start_seq()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
|
||||
set.finish(self)
|
||||
fn end_set(&mut self) -> io::Result<()> {
|
||||
self.finish_seq(Tag::Set, true)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
|
||||
self.write_tag(Tag::Dictionary)?;
|
||||
Ok(BinaryOrderWriter::new())
|
||||
fn start_dictionary(&mut self) -> io::Result<()> {
|
||||
self.start_seq()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
|
||||
dict.finish(self)
|
||||
fn end_dictionary(&mut self) -> io::Result<()> {
|
||||
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)]
|
||||
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
|
||||
self.write_tag(Tag::Embedded)?;
|
||||
Ok(self.suspend())
|
||||
fn start_embedded(&mut self) -> io::Result<()> {
|
||||
self.write_tag(Tag::Embedded);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> io::Result<()> {
|
||||
self.resume(ann);
|
||||
fn end_embedded(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::io;
|
||||
|
@ -6,18 +6,18 @@ use std::marker::PhantomData;
|
|||
|
||||
use super::CompoundClass;
|
||||
use super::DomainDecode;
|
||||
use super::DomainParse;
|
||||
use super::Double;
|
||||
use super::DummyValue;
|
||||
use super::Float;
|
||||
use super::IOValue;
|
||||
use super::IOValueDomainCodec;
|
||||
use super::NestedValue;
|
||||
use super::ViaCodec;
|
||||
use super::boundary as B;
|
||||
use super::signed_integer::SignedInteger;
|
||||
|
||||
pub type ReaderResult<T> = std::result::Result<T, error::Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Token<N: NestedValue> {
|
||||
Embedded(N::Embedded),
|
||||
Atom(N),
|
||||
|
@ -25,16 +25,21 @@ pub enum Token<N: NestedValue> {
|
|||
End,
|
||||
}
|
||||
|
||||
pub trait Reader<'de, N: NestedValue> {
|
||||
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>>;
|
||||
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type>;
|
||||
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item>;
|
||||
fn open_sequence(&mut self) -> ReaderResult<()>;
|
||||
fn open_set(&mut self) -> ReaderResult<()>;
|
||||
fn open_dictionary(&mut self) -> ReaderResult<()>;
|
||||
pub trait Reader<'de> {
|
||||
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Option<N>>;
|
||||
|
||||
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<()>;
|
||||
|
||||
// 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 open_embedded(&mut self) -> ReaderResult<()>;
|
||||
|
@ -44,103 +49,107 @@ pub trait Reader<'de, N: NestedValue> {
|
|||
fn mark(&mut self) -> io::Result<Self::Mark>;
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
|
||||
|
||||
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>>;
|
||||
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, 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>>;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
fn skip_value(&mut self) -> io::Result<()> {
|
||||
// TODO efficient skipping in specific impls of this trait
|
||||
let _ = self.demand_next(false)?;
|
||||
let _: DummyValue<IOValue> = self.demand_next(false, &mut IOValueDomainCodec)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn demand_next(&mut self, read_annotations: bool) -> io::Result<N> {
|
||||
self.next(read_annotations)?.ok_or_else(io_eof)
|
||||
fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
|
||||
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> {
|
||||
self.demand_next(false)?.value().to_boolean()
|
||||
self.next_iovalue(false)?.value().to_boolean()
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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_u8(&mut self) -> ReaderResult<u8> { self.demand_next(false)?.value().to_u8() }
|
||||
fn next_i16(&mut self) -> ReaderResult<i16> { self.demand_next(false)?.value().to_i16() }
|
||||
fn next_u16(&mut self) -> ReaderResult<u16> { self.demand_next(false)?.value().to_u16() }
|
||||
fn next_i32(&mut self) -> ReaderResult<i32> { self.demand_next(false)?.value().to_i32() }
|
||||
fn next_u32(&mut self) -> ReaderResult<u32> { self.demand_next(false)?.value().to_u32() }
|
||||
fn next_i64(&mut self) -> ReaderResult<i64> { self.demand_next(false)?.value().to_i64() }
|
||||
fn next_u64(&mut self) -> ReaderResult<u64> { self.demand_next(false)?.value().to_u64() }
|
||||
fn next_i128(&mut self) -> ReaderResult<i128> { self.demand_next(false)?.value().to_i128() }
|
||||
fn next_u128(&mut self) -> ReaderResult<u128> { self.demand_next(false)?.value().to_u128() }
|
||||
fn next_f32(&mut self) -> ReaderResult<f32> { self.demand_next(false)?.value().to_f32() }
|
||||
fn next_f64(&mut self) -> ReaderResult<f64> { self.demand_next(false)?.value().to_f64() }
|
||||
fn next_char(&mut self) -> ReaderResult<char> { self.demand_next(false)?.value().to_char() }
|
||||
fn next_i8(&mut self) -> ReaderResult<i8> { self.next_iovalue(false)?.value().to_i8() }
|
||||
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_iovalue(false)?.value().to_u8() }
|
||||
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_iovalue(false)?.value().to_i16() }
|
||||
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_iovalue(false)?.value().to_u16() }
|
||||
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_iovalue(false)?.value().to_i32() }
|
||||
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_iovalue(false)?.value().to_u32() }
|
||||
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_iovalue(false)?.value().to_i64() }
|
||||
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_iovalue(false)?.value().to_u64() }
|
||||
fn next_i128(&mut self) -> ReaderResult<i128> { self.next_iovalue(false)?.value().to_i128() }
|
||||
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_iovalue(false)?.value().to_u128() }
|
||||
fn next_f32(&mut self) -> ReaderResult<f32> { self.next_iovalue(false)?.value().to_f32() }
|
||||
fn next_f64(&mut self) -> ReaderResult<f64> { self.next_iovalue(false)?.value().to_f64() }
|
||||
fn next_char(&mut self) -> ReaderResult<char> { self.next_iovalue(false)?.value().to_char() }
|
||||
|
||||
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]>> {
|
||||
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>> {
|
||||
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 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 b = self.open_record()?;
|
||||
let label: &str = &self.next_symbol()?;
|
||||
if label == name {
|
||||
Ok(b)
|
||||
} else {
|
||||
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
|
||||
Received::ReceivedRecordWithLabel(label.to_owned())))
|
||||
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.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
|
||||
Self: std::marker::Sized
|
||||
{
|
||||
ConfiguredReader {
|
||||
reader: self,
|
||||
read_annotations,
|
||||
decode_embedded,
|
||||
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<()> {
|
||||
if !self.close_compound(b, i)? {
|
||||
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 {
|
||||
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
|
||||
(*self).next(read_annotations)
|
||||
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
|
||||
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&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> {
|
||||
(*self).open_record(arity)
|
||||
}
|
||||
|
||||
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
|
||||
(*self).open_sequence_or_set()
|
||||
fn open_record(&mut self) -> ReaderResult<()> {
|
||||
(*self).open_record()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
|
||||
(*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>>(
|
||||
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
decode_embedded: Dec,
|
||||
) -> super::PackedReader<'de, '_, N, Dec, Self> {
|
||||
super::PackedReader::new(self, 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))
|
||||
read_embedded_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Token<N>> {
|
||||
(*self).next_token(read_embedded_annotations, decode_embedded)
|
||||
}
|
||||
}
|
||||
|
||||
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<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 struct ConfiguredReader<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
|
||||
{
|
||||
pub reader: R,
|
||||
pub read_annotations: bool,
|
||||
pub decode_embedded: Dec,
|
||||
phantom: PhantomData<&'de N>,
|
||||
}
|
||||
|
||||
impl<'de, N: NestedValue, R: Reader<'de, N>> ConfiguredReader<'de, N, R> {
|
||||
pub fn new(reader: R) -> Self {
|
||||
reader.configured(true)
|
||||
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
|
||||
ConfiguredReader<'de, N, Dec, R>
|
||||
{
|
||||
pub fn new(reader: R, decode_embedded: Dec) -> Self {
|
||||
reader.configured(true, decode_embedded)
|
||||
}
|
||||
|
||||
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> {
|
||||
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>;
|
||||
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)),
|
||||
Ok(None) => None,
|
||||
Ok(Some(v)) => Some(Ok(v)),
|
||||
|
|
|
@ -17,7 +17,7 @@ pub use std::collections::BTreeSet as Set;
|
|||
pub use std::collections::BTreeMap as Map;
|
||||
|
||||
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 Embeddable: Domain + Clone {}
|
||||
|
@ -398,7 +398,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
|
||||
fn expected(&self, k: ExpectedKind) -> Error {
|
||||
Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap())))
|
||||
Error::Expected(k)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -877,7 +877,7 @@ impl<N: NestedValue> Value<N> {
|
|||
|
||||
#[inline(always)]
|
||||
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)]
|
||||
|
@ -917,7 +917,7 @@ impl<N: NestedValue> Value<N> {
|
|||
Result<&[N], Error>
|
||||
{
|
||||
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)]
|
||||
|
@ -1515,22 +1515,22 @@ impl<D: Embeddable> NestedValue for DummyValue<D> {
|
|||
|
||||
#[inline(always)]
|
||||
fn annotations(&self) -> &Annotations<Self> {
|
||||
&self.0.0
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value(&self) -> &Value<Self> {
|
||||
&self.0.1
|
||||
&(self.0).1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
|
||||
(self.0.0, self.0.1)
|
||||
((self.0).0, (self.0).1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value_owned(self) -> Value<Self> {
|
||||
self.0.1
|
||||
(self.0).1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -4,30 +4,30 @@ pub mod writer;
|
|||
pub use reader::TextReader;
|
||||
pub use writer::TextWriter;
|
||||
|
||||
use crate::value::reader::BytesBinarySource;
|
||||
use crate::value::source::BytesBinarySource;
|
||||
|
||||
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,
|
||||
decode_embedded: Dec,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> 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> {
|
||||
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,
|
||||
decode_embedded: Dec,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> 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> {
|
||||
annotated_from_str(s, ViaCodec::new(IOValueDomainCodec))
|
||||
annotated_from_str(s, &mut IOValueDomainCodec)
|
||||
}
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
use crate::error::Error;
|
||||
use crate::error::ExpectedKind;
|
||||
use crate::error::Received;
|
||||
use crate::error::io_eof;
|
||||
use crate::error::io_syntax_error;
|
||||
use crate::error::is_eof_io_error;
|
||||
use crate::error::syntax_error;
|
||||
|
||||
use crate::hex;
|
||||
|
||||
use crate::value::CompoundClass;
|
||||
use crate::value::DomainParse;
|
||||
use crate::value::DummyValue;
|
||||
use crate::value::Embeddable;
|
||||
use crate::value::IOValue;
|
||||
use crate::value::IOValueDomainCodec;
|
||||
use crate::value::DomainDecode;
|
||||
use crate::value::Map;
|
||||
use crate::value::NestedValue;
|
||||
use crate::value::Reader;
|
||||
|
@ -20,11 +14,10 @@ use crate::value::Record;
|
|||
use crate::value::Set;
|
||||
use crate::value::Token;
|
||||
use crate::value::Value;
|
||||
use crate::value::ViaCodec;
|
||||
use crate::value::boundary as B;
|
||||
use crate::value::reader::BinarySource;
|
||||
use crate::value::reader::ReaderResult;
|
||||
use crate::value::repr::Annotations;
|
||||
use crate::value::source::BinarySource;
|
||||
|
||||
use num::bigint::BigInt;
|
||||
|
||||
|
@ -32,10 +25,9 @@ use std::io;
|
|||
use std::iter::FromIterator;
|
||||
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 dec: Dec,
|
||||
phantom: PhantomData<&'de D>,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
|
||||
TextReader<'de, 'src, D, Dec, S>
|
||||
{
|
||||
pub fn new(source: &'src mut S, dec: Dec) -> Self {
|
||||
impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S> {
|
||||
pub fn new(source: &'src mut S) -> Self {
|
||||
TextReader {
|
||||
source,
|
||||
dec,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn peek(&mut self) -> io::Result<u8> {
|
||||
fn peek(&mut self) -> io::Result<Option<u8>> {
|
||||
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<()> {
|
||||
self.source.skip()
|
||||
}
|
||||
|
||||
fn next_byte(&mut self) -> io::Result<u8> {
|
||||
let b = self.source.peek()?;
|
||||
let b = self.peek_noeof()?;
|
||||
self.source.skip()?;
|
||||
Ok(b)
|
||||
}
|
||||
|
||||
fn skip_whitespace(&mut self) {
|
||||
// Deliberately swallows errors.
|
||||
while let Ok(c) = self.peek() {
|
||||
while let Ok(Some(c)) = self.peek() {
|
||||
match c {
|
||||
b' ' | b'\t' | b'\r' | b'\n' | b',' => {
|
||||
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<N: NestedValue<Embedded = D>>(&mut self, k: ExpectedKind) -> Error {
|
||||
match Reader::<N>::demand_next(self, true) {
|
||||
Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
|
||||
Err(e) => e.into()
|
||||
}
|
||||
fn expected(&mut self, k: ExpectedKind) -> Error {
|
||||
Error::Expected(k)
|
||||
}
|
||||
|
||||
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();
|
||||
loop {
|
||||
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(self.demand_next(true)?) }
|
||||
b'@' => { self.skip()?; vs.push(self.demand_next(true, decode_embedded)?) }
|
||||
_ => return Ok(vs),
|
||||
}
|
||||
}
|
||||
|
@ -111,24 +104,18 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
|
|||
fn skip_annotations(&mut self) -> ReaderResult<()> {
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
match self.peek()? {
|
||||
match self.peek_noeof()? {
|
||||
b';' => { self.skip()?; self.comment_line()?; },
|
||||
b'@' => { self.skip()?; Reader::<DummyValue<D>>::skip_value(self)?; },
|
||||
b'@' => { self.skip()?; self.skip_value()?; },
|
||||
_ => 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> {
|
||||
let mut bs = Vec::new();
|
||||
loop {
|
||||
let b = self.peek()?;
|
||||
let b = self.peek_noeof()?;
|
||||
self.skip()?;
|
||||
match b {
|
||||
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> {
|
||||
let mut is_float = false;
|
||||
match self.peek() {
|
||||
match self.peek_noeof() {
|
||||
Ok(b'.') => {
|
||||
is_float = true;
|
||||
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') => {
|
||||
bs.push(self.next_byte()?);
|
||||
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> {
|
||||
match self.peek()? {
|
||||
match self.peek_noeof()? {
|
||||
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> {
|
||||
let s = decode_utf8(bs)?;
|
||||
if is_float {
|
||||
match self.peek() {
|
||||
match self.peek_noeof() {
|
||||
Ok(b'f') | Ok(b'F') => {
|
||||
self.skip()?;
|
||||
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"));
|
||||
}
|
||||
bs.push(c);
|
||||
while let Ok(c) = self.peek() {
|
||||
while let Ok(Some(c)) = self.peek() {
|
||||
if !(c as char).is_digit(10) {
|
||||
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();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
if self.peek()? == delimiter {
|
||||
if self.peek()? == Some(delimiter) {
|
||||
self.skip()?;
|
||||
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();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
if self.peek()? == b'}' {
|
||||
if self.peek_noeof()? == b'}' {
|
||||
self.skip()?;
|
||||
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();
|
||||
if self.next_byte()? != b':' {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_raw_symbol<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
|
||||
loop {
|
||||
let c = match self.peek() {
|
||||
Err(e) if is_eof_io_error(&e) => b' ',
|
||||
Err(e) => return Err(e)?,
|
||||
Ok(c) if (c as char).is_whitespace() => b' ',
|
||||
Ok(c) => c
|
||||
let c = match self.peek()? {
|
||||
None => b' ',
|
||||
Some(c) if (c as char).is_whitespace() => b' ',
|
||||
Some(c) => c
|
||||
};
|
||||
match c {
|
||||
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>>
|
||||
Reader<'de, N> for TextReader<'de, 'src, N::Embedded, Dec, S>
|
||||
{
|
||||
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
|
||||
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for TextReader<'de, 'src, S> {
|
||||
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Option<N>> {
|
||||
self.skip_whitespace();
|
||||
let c = match self.peek() {
|
||||
Ok(c) => c,
|
||||
Err(e) if is_eof_io_error(&e) => return Ok(None),
|
||||
Err(e) => return Err(e.into()),
|
||||
let c = match self.peek()? {
|
||||
None => return Ok(None),
|
||||
Some(c) => c,
|
||||
};
|
||||
Ok(Some(match c {
|
||||
b'-' => {
|
||||
|
@ -415,14 +411,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
}
|
||||
b';' | b'@' => {
|
||||
if read_annotations {
|
||||
let mut annotations = self.gather_annotations()?;
|
||||
let (existing_annotations, v) =
|
||||
Reader::<N>::demand_next(self, read_annotations)?.pieces();
|
||||
let mut annotations = self.gather_annotations(decode_embedded)?;
|
||||
let av: N = self.demand_next(read_annotations, decode_embedded)?;
|
||||
let (existing_annotations, v) = av.pieces();
|
||||
annotations.extend_from_slice(existing_annotations.slice());
|
||||
N::wrap(Annotations::new(Some(annotations)), v)
|
||||
} else {
|
||||
self.skip_annotations()?;
|
||||
self.demand_next(read_annotations)?
|
||||
self.demand_next(read_annotations, decode_embedded)?
|
||||
}
|
||||
}
|
||||
b':' => {
|
||||
|
@ -433,7 +429,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
match self.next_byte()? {
|
||||
b'f' => N::new(false),
|
||||
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'x' => if self.next_byte()? == b'"' {
|
||||
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'=' => {
|
||||
let bs_val: N = self.demand_next(true)?;
|
||||
let bs_val = self.next_iovalue(true)?;
|
||||
if bs_val.annotations().slice().len() > 0 {
|
||||
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 #=")),
|
||||
Some(bs) =>
|
||||
crate::value::BytesBinarySource::new(bs)
|
||||
.packed(ViaCodec::new(&mut self.dec))
|
||||
.demand_next(read_annotations)?
|
||||
.packed()
|
||||
.demand_next(read_annotations, decode_embedded)?
|
||||
}
|
||||
}
|
||||
b'!' => {
|
||||
let v = self.next_iovalue(read_annotations)?;
|
||||
Value::Embedded(self.dec.parse_embedded(&v)?).wrap()
|
||||
}
|
||||
b'!' => Value::Embedded(
|
||||
decode_embedded.decode_embedded(self, read_annotations)?).wrap(),
|
||||
other => return Err(io_syntax_error(&format!("Invalid # syntax: {:?}", other))),
|
||||
}
|
||||
}
|
||||
b'<' => {
|
||||
self.skip()?;
|
||||
let vs = self.upto(b'>', read_annotations)?;
|
||||
let vs = self.upto(b'>', read_annotations, decode_embedded)?;
|
||||
if vs.is_empty() {
|
||||
return Err(io_syntax_error("Missing record label"));
|
||||
}
|
||||
|
@ -472,11 +467,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
}
|
||||
b'[' => {
|
||||
self.skip()?;
|
||||
N::new(self.upto(b']', read_annotations)?)
|
||||
N::new(self.upto(b']', read_annotations, decode_embedded)?)
|
||||
}
|
||||
b'{' => {
|
||||
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 ]")),
|
||||
|
@ -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()?;
|
||||
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()?;
|
||||
let mut b = B::Type::default();
|
||||
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))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn open_sequence(&mut self) -> ReaderResult<()> {
|
||||
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()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn open_set(&mut self) -> ReaderResult<()> {
|
||||
self.skip_annotations()?;
|
||||
let mark = Reader::<N>::mark(self)?;
|
||||
let mark = self.mark()?;
|
||||
match self.next_byte()? {
|
||||
b'#' => match self.next_byte()? {
|
||||
b'{' => return Ok(()),
|
||||
|
@ -529,13 +507,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
},
|
||||
_ => (),
|
||||
}
|
||||
Reader::<N>::restore(self, &mark)?;
|
||||
Err(self.expected::<N>(ExpectedKind::Set))
|
||||
self.restore(&mark)?;
|
||||
Err(self.expected(ExpectedKind::Set))
|
||||
}
|
||||
|
||||
fn open_dictionary(&mut self) -> ReaderResult<()> {
|
||||
self.skip_annotations()?;
|
||||
if self.peek()? != b'{' { return Err(self.expected::<N>(ExpectedKind::Dictionary)); }
|
||||
if self.peek()? != Some(b'{') { return Err(self.expected(ExpectedKind::Dictionary)); }
|
||||
self.skip()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -549,7 +527,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
} => {
|
||||
self.skip_whitespace();
|
||||
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> {
|
||||
self.skip_whitespace();
|
||||
match self.peek()? {
|
||||
match self.peek_noeof()? {
|
||||
b'>' | b']' | b'}' => {
|
||||
self.skip()?;
|
||||
Ok(true)
|
||||
}
|
||||
_ => {
|
||||
b.shift(Some(i.clone()));
|
||||
Reader::<N>::boundary(self, b)?;
|
||||
self.boundary(b)?;
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
@ -574,7 +552,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
|
||||
fn open_embedded(&mut self) -> ReaderResult<()> {
|
||||
self.skip_annotations()?;
|
||||
let mark = Reader::<N>::mark(self)?;
|
||||
let mark = self.mark()?;
|
||||
match self.next_byte()? {
|
||||
b'#' => match self.next_byte()? {
|
||||
b'!' => return Ok(()),
|
||||
|
@ -582,8 +560,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
|
|||
},
|
||||
_ => (),
|
||||
}
|
||||
Reader::<N>::restore(self, &mark)?;
|
||||
Err(self.expected::<N>(ExpectedKind::Embedded))
|
||||
self.restore(&mark)?;
|
||||
Err(self.expected(ExpectedKind::Embedded))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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()?;
|
||||
let mark = Reader::<N>::mark(self)?;
|
||||
let mark = self.mark()?;
|
||||
Ok(match self.next_byte()? {
|
||||
b'<' => Token::Compound(CompoundClass::Record),
|
||||
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'#' => match self.next_byte()? {
|
||||
b'!' => {
|
||||
let v = self.next_iovalue(read_embedded_annotations)?;
|
||||
Token::Embedded(self.dec.parse_embedded(&v)?)
|
||||
}
|
||||
b'!' => Token::Embedded(decode_embedded.decode_embedded(
|
||||
self, read_embedded_annotations)?),
|
||||
b'{' => Token::Compound(CompoundClass::Set),
|
||||
_ => {
|
||||
Reader::<N>::restore(self, &mark)?;
|
||||
Token::Atom(self.demand_next(false)?)
|
||||
self.restore(&mark)?;
|
||||
Token::Atom(self.demand_next(false, decode_embedded)?)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Reader::<N>::restore(self, &mark)?;
|
||||
Token::Atom(self.demand_next(false)?)
|
||||
self.restore(&mark)?;
|
||||
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)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ use crate::value::IOValue;
|
|||
use crate::value::IOValueDomainCodec;
|
||||
use crate::value::NestedValue;
|
||||
use crate::value::Writer;
|
||||
use crate::value::suspendable::Suspendable;
|
||||
use crate::value::writer::CompoundWriter;
|
||||
|
||||
use num::bigint::BigInt;
|
||||
|
||||
|
@ -20,7 +18,7 @@ pub enum CommaStyle {
|
|||
}
|
||||
|
||||
pub struct TextWriter<W: io::Write> {
|
||||
w: Suspendable<W>,
|
||||
w: W,
|
||||
pub comma_style: CommaStyle,
|
||||
pub indentation: usize,
|
||||
pub escape_spaces: bool,
|
||||
|
@ -51,7 +49,7 @@ impl TextWriter<&mut Vec<u8>> {
|
|||
impl<W: io::Write> TextWriter<W> {
|
||||
pub fn new(w: W) -> Self {
|
||||
TextWriter {
|
||||
w: Suspendable::new(w),
|
||||
w,
|
||||
comma_style: CommaStyle::default(),
|
||||
indentation: 0,
|
||||
escape_spaces: false,
|
||||
|
@ -69,14 +67,6 @@ impl<W: io::Write> TextWriter<W> {
|
|||
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>(
|
||||
&mut self,
|
||||
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]
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
|
||||
match (b.closing.as_ref(), b.opening.as_ref()) {
|
||||
|
@ -187,29 +184,12 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
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 start_annotations(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
|
||||
self.resume(ann);
|
||||
fn end_annotations(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -218,12 +198,12 @@ impl<W: io::Write> Writer for TextWriter<W> {
|
|||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
fn write_f64(&mut self, v: f64) -> io::Result<()> {
|
||||
dtoa::write(&mut *self.w, v)?;
|
||||
dtoa::write(&mut self.w, v)?;
|
||||
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, "<")?;
|
||||
Ok(self.suspend())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
|
||||
self.resume(rec);
|
||||
fn end_record(&mut self) -> io::Result<()> {
|
||||
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, "[")?;
|
||||
Ok(self.suspend())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
|
||||
self.resume(seq);
|
||||
fn end_sequence(&mut self) -> io::Result<()> {
|
||||
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, "#{{")?;
|
||||
Ok(self.suspend())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
|
||||
self.resume(set);
|
||||
fn end_set(&mut self) -> io::Result<()> {
|
||||
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, "{{")?;
|
||||
Ok(self.suspend())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
|
||||
self.resume(dict);
|
||||
fn end_dictionary(&mut self) -> io::Result<()> {
|
||||
write!(self.w, "}}")
|
||||
}
|
||||
|
||||
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
|
||||
fn start_embedded(&mut self) -> io::Result<()> {
|
||||
write!(self.w, "#!")?;
|
||||
Ok(self.suspend())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
|
||||
self.resume(ptr);
|
||||
fn end_embedded(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,9 @@ use super::boundary as B;
|
|||
use super::signed_integer::SignedIntegerRepr;
|
||||
use super::repr::{Value, NestedValue, Float, Double};
|
||||
|
||||
pub trait CompoundWriter: Writer {
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
|
||||
}
|
||||
|
||||
pub trait Writer: Sized {
|
||||
type AnnWriter: CompoundWriter;
|
||||
type RecWriter: CompoundWriter;
|
||||
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 start_annotations(&mut self) -> io::Result<()>;
|
||||
fn end_annotations(&mut self) -> 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_symbol(&mut self, v: &str) -> io::Result<()>;
|
||||
|
||||
fn start_record(&mut self, field_count: Option<usize>) -> io::Result<Self::RecWriter>;
|
||||
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()>;
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
|
||||
|
||||
fn start_sequence(&mut self, item_count: Option<usize>) -> io::Result<Self::SeqWriter>;
|
||||
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()>;
|
||||
fn start_record(&mut self) -> io::Result<()>;
|
||||
fn end_record(&mut self) -> io::Result<()>;
|
||||
|
||||
fn start_set(&mut self, item_count: Option<usize>) -> io::Result<Self::SetWriter>;
|
||||
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()>;
|
||||
fn start_sequence(&mut self) -> io::Result<()>;
|
||||
fn end_sequence(&mut self) -> io::Result<()>;
|
||||
|
||||
fn start_dictionary(&mut self, entry_count: Option<usize>) -> io::Result<Self::DictWriter>;
|
||||
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()>;
|
||||
fn start_set(&mut self) -> io::Result<()>;
|
||||
fn end_set(&mut self) -> io::Result<()>;
|
||||
|
||||
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter>;
|
||||
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()>;
|
||||
fn start_dictionary(&mut self) -> 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<()>;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#[inline(always)]
|
||||
fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
|
||||
&mut self,
|
||||
enc: &mut Enc,
|
||||
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<()> {
|
||||
match v.annotations().maybe_slice() {
|
||||
None => {
|
||||
self.write_value(enc, v.value())?;
|
||||
}
|
||||
Some(anns) => {
|
||||
let mut a = self.start_annotations()?;
|
||||
self.start_annotations()?;
|
||||
let mut b = B::Type::default();
|
||||
for ann in anns {
|
||||
b.shift(Some(B::Item::Annotation));
|
||||
a.boundary(&b)?;
|
||||
a.write(enc, ann)?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, ann)?;
|
||||
}
|
||||
b.shift(Some(B::Item::AnnotatedValue));
|
||||
a.boundary(&b)?;
|
||||
a.write_value(enc, v.value())?;
|
||||
self.boundary(&b)?;
|
||||
self.write_value(enc, v.value())?;
|
||||
b.shift(None);
|
||||
a.boundary(&b)?;
|
||||
self.end_annotations(a)?;
|
||||
self.boundary(&b)?;
|
||||
self.end_annotations()?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -106,77 +106,63 @@ pub trait Writer: Sized {
|
|||
Value::ByteString(bs) => self.write_bytes(bs),
|
||||
Value::Symbol(s) => self.write_symbol(s),
|
||||
Value::Record(r) => {
|
||||
let mut c = self.start_record(Some(r.arity()))?;
|
||||
self.start_record()?;
|
||||
let mut b = B::start(B::Item::RecordLabel);
|
||||
c.boundary(&b)?;
|
||||
c.write(enc, r.label())?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, r.label())?;
|
||||
for f in r.fields() {
|
||||
b.shift(Some(B::Item::RecordField));
|
||||
c.boundary(&b)?;
|
||||
c.write(enc, f)?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, f)?;
|
||||
}
|
||||
b.shift(None);
|
||||
c.boundary(&b)?;
|
||||
self.end_record(c)
|
||||
self.boundary(&b)?;
|
||||
self.end_record()
|
||||
}
|
||||
Value::Sequence(vs) => {
|
||||
let mut c = self.start_sequence(Some(vs.len()))?;
|
||||
self.start_sequence()?;
|
||||
let mut b = B::Type::default();
|
||||
for v in vs {
|
||||
b.shift(Some(B::Item::SequenceValue));
|
||||
c.boundary(&b)?;
|
||||
c.write(enc, v)?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, v)?;
|
||||
}
|
||||
b.shift(None);
|
||||
c.boundary(&b)?;
|
||||
self.end_sequence(c)
|
||||
self.boundary(&b)?;
|
||||
self.end_sequence()
|
||||
}
|
||||
Value::Set(vs) => {
|
||||
let mut c = self.start_set(Some(vs.len()))?;
|
||||
self.start_set()?;
|
||||
let mut b = B::Type::default();
|
||||
for v in vs {
|
||||
b.shift(Some(B::Item::SetValue));
|
||||
c.boundary(&b)?;
|
||||
c.write(enc, v)?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, v)?;
|
||||
}
|
||||
b.shift(None);
|
||||
c.boundary(&b)?;
|
||||
self.end_set(c)
|
||||
self.boundary(&b)?;
|
||||
self.end_set()
|
||||
}
|
||||
Value::Dictionary(vs) => {
|
||||
let mut c = self.start_dictionary(Some(vs.len()))?;
|
||||
self.start_dictionary()?;
|
||||
let mut b = B::Type::default();
|
||||
for (k, v) in vs {
|
||||
b.shift(Some(B::Item::DictionaryKey));
|
||||
c.boundary(&b)?;
|
||||
c.write(enc, k)?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, k)?;
|
||||
b.shift(Some(B::Item::DictionaryValue));
|
||||
c.boundary(&b)?;
|
||||
c.write(enc, v)?;
|
||||
self.boundary(&b)?;
|
||||
self.inner_write(enc, v)?;
|
||||
}
|
||||
b.shift(None);
|
||||
c.boundary(&b)?;
|
||||
self.end_dictionary(c)
|
||||
self.boundary(&b)?;
|
||||
self.end_dictionary()
|
||||
}
|
||||
Value::Embedded(d) => {
|
||||
let mut c = self.start_embedded()?;
|
||||
enc.encode_embedded(&mut c, d)?;
|
||||
self.end_embedded(c)
|
||||
self.start_embedded()?;
|
||||
enc.encode_embedded(self, d)?;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ mod samples;
|
|||
use samples::*;
|
||||
|
||||
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<()> {
|
||||
|
@ -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 contents = String::new();
|
||||
fh.read_to_string(&mut contents)?;
|
||||
preserves::value::TextReader::new(
|
||||
&mut BytesBinarySource::new(contents.as_bytes()),
|
||||
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec))
|
||||
.next_iovalue(true)?
|
||||
BytesBinarySource::new(contents.as_bytes()).text().next_iovalue(true)?
|
||||
};
|
||||
let from_packed = {
|
||||
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);
|
||||
Ok(())
|
||||
|
@ -105,7 +102,7 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
|
|||
#[test] fn run() -> io::Result<()> {
|
||||
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
|
||||
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();
|
||||
|
||||
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) => {
|
||||
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)
|
||||
} else {
|
||||
false
|
||||
})
|
||||
}
|
||||
TestCase::DecodeEOF(ref bin) => {
|
||||
assert!(BytesBinarySource::new(bin).packed_iovalues().configured(true).next().is_none());
|
||||
assert!(BytesBinarySource::new(bin).packed().iovalues().next().is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue