forked from syndicate-lang/preserves
Update Rust implementation
This commit is contained in:
parent
ca2276d268
commit
a1a604aee8
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "preserves"
|
name = "preserves"
|
||||||
version = "0.9.0"
|
version = "0.10.0"
|
||||||
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
|
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Implementation of the Preserves serialization format via serde."
|
description = "Implementation of the Preserves serialization format via serde."
|
||||||
|
@ -13,7 +13,6 @@ gitlab = { repository = "preserves/preserves" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num = "0.2"
|
num = "0.2"
|
||||||
num_enum = "0.4.1"
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_bytes = "0.11"
|
serde_bytes = "0.11"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub fn bench_encoder(c: &mut Criterion) {
|
||||||
let v = PackedReader::decode_read(&mut fh).demand_next(true).unwrap();
|
let v = PackedReader::decode_read(&mut fh).demand_next(true).unwrap();
|
||||||
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| {
|
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| {
|
||||||
let mut bs = vec![];
|
let mut bs = vec![];
|
||||||
PackedWriter(&mut bs).write(&v).unwrap();
|
PackedWriter::new(&mut bs).write(&v).unwrap();
|
||||||
bs
|
bs
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ pub fn bench_ser(c: &mut Criterion) {
|
||||||
let v: TestCases = de::from_read(&mut fh).unwrap();
|
let v: TestCases = de::from_read(&mut fh).unwrap();
|
||||||
c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| {
|
c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| {
|
||||||
let mut bs = vec![];
|
let mut bs = vec![];
|
||||||
ser::to_writer(&mut PackedWriter(&mut bs), &v).unwrap();
|
ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap();
|
||||||
bs
|
bs
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ pub fn bench_ser_encoder(c: &mut Criterion) {
|
||||||
let v: TestCases = de::from_read(&mut fh).unwrap();
|
let v: TestCases = de::from_read(&mut fh).unwrap();
|
||||||
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| {
|
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| {
|
||||||
let mut bs = vec![];
|
let mut bs = vec![];
|
||||||
PackedWriter(&mut bs).write(&value::ser::to_value(&v)).unwrap();
|
PackedWriter::new(&mut bs).write(&value::ser::to_value(&v)).unwrap();
|
||||||
bs
|
bs
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
|
||||||
}
|
}
|
||||||
b.iter_with_large_drop(|| {
|
b.iter_with_large_drop(|| {
|
||||||
let mut bs = vec![];
|
let mut bs = vec![];
|
||||||
let mut w = PackedWriter(&mut bs);
|
let mut w = PackedWriter::new(&mut bs);
|
||||||
for v in &vs {
|
for v in &vs {
|
||||||
w.write(&v).unwrap();
|
w.write(&v).unwrap();
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, Deseri
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use super::value::PackedReader;
|
use super::value::PackedReader;
|
||||||
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource, CompoundBody};
|
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
|
||||||
|
|
||||||
pub use super::error::Error;
|
pub use super::error::Error;
|
||||||
|
|
||||||
|
@ -144,31 +144,31 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
|
||||||
|
|
||||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
||||||
{
|
{
|
||||||
let (is_some, mut compound_body) = self.read.open_option()?;
|
let is_some = self.read.open_option()?;
|
||||||
let result = if is_some {
|
let result = if is_some {
|
||||||
compound_body.ensure_more_expected(self.read)?;
|
self.read.ensure_more_expected()?;
|
||||||
visitor.visit_some(&mut *self)?
|
visitor.visit_some(&mut *self)?
|
||||||
} else {
|
} else {
|
||||||
visitor.visit_none::<Error>()?
|
visitor.visit_none::<Error>()?
|
||||||
};
|
};
|
||||||
compound_body.ensure_complete(self.read)?;
|
self.read.ensure_complete()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
||||||
{
|
{
|
||||||
let mut compound_body = self.read.open_simple_record("tuple", Some(0))?;
|
self.read.open_simple_record("tuple", Some(0))?;
|
||||||
let result = visitor.visit_unit::<Error>()?;
|
let result = visitor.visit_unit::<Error>()?;
|
||||||
compound_body.ensure_complete(self.read)?;
|
self.read.ensure_complete()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
|
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
|
||||||
-> Result<V::Value> where V: Visitor<'de>
|
-> Result<V::Value> where V: Visitor<'de>
|
||||||
{
|
{
|
||||||
let mut compound_body = self.read.open_simple_record(name, Some(0))?;
|
self.read.open_simple_record(name, Some(0))?;
|
||||||
let result = visitor.visit_unit::<Error>()?;
|
let result = visitor.visit_unit::<Error>()?;
|
||||||
compound_body.ensure_complete(self.read)?;
|
self.read.ensure_complete()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +180,10 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
|
||||||
{
|
{
|
||||||
Some(v) => visitor.visit_u64(v),
|
Some(v) => visitor.visit_u64(v),
|
||||||
None => {
|
None => {
|
||||||
let mut compound_body = self.read.open_simple_record(name, Some(1))?;
|
self.read.open_simple_record(name, Some(1))?;
|
||||||
compound_body.ensure_more_expected(self.read)?;
|
self.read.ensure_more_expected()?;
|
||||||
let result = visitor.visit_newtype_struct(&mut *self)?;
|
let result = visitor.visit_newtype_struct(&mut *self)?;
|
||||||
compound_body.ensure_complete(self.read)?;
|
self.read.ensure_complete()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,14 +192,14 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
||||||
// Hack around serde's model: Deserialize *sets* as sequences,
|
// Hack around serde's model: Deserialize *sets* as sequences,
|
||||||
// too, and reconstruct them as Rust Sets on the visitor side.
|
// too, and reconstruct them as Rust Sets on the visitor side.
|
||||||
let compound_body = self.read.open_sequence_or_set()?;
|
self.read.open_sequence_or_set()?;
|
||||||
visitor.visit_seq(Seq::new(self, compound_body))
|
visitor.visit_seq(Seq::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
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 compound_body = self.read.open_simple_record("tuple", Some(len))?;
|
self.read.open_simple_record("tuple", Some(len))?;
|
||||||
let mut seq = Seq::new(self, compound_body);
|
let mut seq = Seq::new(self);
|
||||||
let result = visitor.visit_seq(&mut seq)?;
|
let result = visitor.visit_seq(&mut seq)?;
|
||||||
seq.skip_remainder()?;
|
seq.skip_remainder()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -208,18 +208,17 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
|
||||||
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
|
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
|
||||||
-> Result<V::Value> where V: Visitor<'de>
|
-> Result<V::Value> where V: Visitor<'de>
|
||||||
{
|
{
|
||||||
let compound_body = self.read.open_simple_record(name, Some(len))?;
|
self.read.open_simple_record(name, Some(len))?;
|
||||||
let mut seq = Seq::new(self, compound_body);
|
let mut seq = Seq::new(self);
|
||||||
let result = visitor.visit_seq(&mut seq)?;
|
let result = visitor.visit_seq(&mut seq)?;
|
||||||
seq.skip_remainder()?;
|
seq.skip_remainder()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
||||||
let compound_body = self.read.open_dictionary()?;
|
self.read.open_dictionary()?;
|
||||||
let mut seq = Seq::new(self, compound_body);
|
let mut seq = Seq::new(self);
|
||||||
let result = visitor.visit_map(&mut seq)?;
|
let result = visitor.visit_map(&mut seq)?;
|
||||||
seq.skip_remainder()?;
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,8 +228,8 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
|
||||||
visitor: V)
|
visitor: V)
|
||||||
-> Result<V::Value> where V: Visitor<'de>
|
-> Result<V::Value> where V: Visitor<'de>
|
||||||
{
|
{
|
||||||
let compound_body = self.read.open_simple_record(name, Some(fields.len()))?;
|
self.read.open_simple_record(name, Some(fields.len()))?;
|
||||||
let mut seq = Seq::new(self, compound_body);
|
let mut seq = Seq::new(self);
|
||||||
let result = visitor.visit_seq(&mut seq)?;
|
let result = visitor.visit_seq(&mut seq)?;
|
||||||
seq.skip_remainder()?;
|
seq.skip_remainder()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -261,24 +260,23 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
|
||||||
|
|
||||||
pub struct Seq<'de, 'r, 'a, R: Reader<'de>> {
|
pub struct Seq<'de, 'r, 'a, R: Reader<'de>> {
|
||||||
de: &'a mut Deserializer<'de, 'r, R>,
|
de: &'a mut Deserializer<'de, 'r, R>,
|
||||||
compound_body: CompoundBody<R::CompoundInfo>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'r, 'a, R: Reader<'de>> 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>, compound_body: CompoundBody<R::CompoundInfo>) -> Self {
|
fn new(de: &'a mut Deserializer<'de, 'r, R>) -> Self {
|
||||||
Seq { de, compound_body }
|
Seq { de }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_remainder(&mut self) -> Result<()> {
|
fn skip_remainder(&mut self) -> Result<()> {
|
||||||
self.compound_body.skip_remainder(self.de.read)
|
self.de.read.skip_remainder()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_item<T>(&mut self, seed: T) ->
|
fn next_item<T>(&mut self, seed: T) ->
|
||||||
Result<Option<T::Value>> where T: DeserializeSeed<'de>
|
Result<Option<T::Value>> where T: DeserializeSeed<'de>
|
||||||
{
|
{
|
||||||
match self.compound_body.more_expected(self.de.read)? {
|
match self.de.read.close_compound()? {
|
||||||
false => Ok(None),
|
true => Ok(None),
|
||||||
true => Ok(Some(seed.deserialize(&mut *self.de)?)),
|
false => Ok(Some(seed.deserialize(&mut *self.de)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,10 +317,9 @@ impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de,
|
||||||
fn variant_seed<V>(self, seed: V)
|
fn variant_seed<V>(self, seed: V)
|
||||||
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
|
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
|
||||||
{
|
{
|
||||||
let mut compound_body = self.read.open_record(None)?;
|
self.read.open_record(None)?;
|
||||||
compound_body.ensure_more_expected(self.read)?;
|
|
||||||
let variant = seed.deserialize(&mut *self)?;
|
let variant = seed.deserialize(&mut *self)?;
|
||||||
Ok((variant, Seq::new(self, compound_body)))
|
Ok((variant, Seq::new(self)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ mod dom {
|
||||||
impl Domain for Dom {
|
impl Domain for Dom {
|
||||||
fn as_preserves(&self) -> Result<IOValue, std::io::Error> {
|
fn as_preserves(&self) -> Result<IOValue, std::io::Error> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
// TODO: How to nicely expose streaming values?
|
|
||||||
Dom::One => Value::ByteString(vec![255, 255, 255, 255]).wrap(),
|
Dom::One => Value::ByteString(vec![255, 255, 255, 255]).wrap(),
|
||||||
Dom::Two => Value::symbol(&format!("Dom::{:?}", self)).wrap(),
|
Dom::Two => Value::symbol(&format!("Dom::{:?}", self)).wrap(),
|
||||||
})
|
})
|
||||||
|
@ -37,7 +36,7 @@ mod dom {
|
||||||
Value::from(2).wrap()])
|
Value::from(2).wrap()])
|
||||||
.wrap();
|
.wrap();
|
||||||
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
|
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
|
||||||
[147, 49, 100, 255, 255, 255, 255, 50]);
|
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn test_two() {
|
#[test] fn test_two() {
|
||||||
|
@ -46,7 +45,7 @@ mod dom {
|
||||||
Value::from(2).wrap()])
|
Value::from(2).wrap()])
|
||||||
.wrap();
|
.wrap();
|
||||||
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
|
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
|
||||||
[147, 49, 120, 68, 111, 109, 58, 58, 84, 119, 111, 50]);
|
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,12 +244,12 @@ mod decoder_tests {
|
||||||
match r {
|
match r {
|
||||||
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
|
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
|
||||||
Err(Error::Expected(k1, _)) if k1 == k => (),
|
Err(Error::Expected(k1, _)) if k1 == k => (),
|
||||||
Err(e) => panic!("Expected Expected({:?}, but got an error of {:?}", k, e),
|
Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn skip_annotations_noskip() {
|
#[test] fn skip_annotations_noskip() {
|
||||||
let mut buf = &b"\x0521"[..];
|
let mut buf = &b"\x85\x92\x91"[..];
|
||||||
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
||||||
let v = d.demand_next().unwrap();
|
let v = d.demand_next().unwrap();
|
||||||
assert_eq!(v.annotations().slice().len(), 1);
|
assert_eq!(v.annotations().slice().len(), 1);
|
||||||
|
@ -259,7 +258,7 @@ mod decoder_tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn skip_annotations_skip() {
|
#[test] fn skip_annotations_skip() {
|
||||||
let mut buf = &b"\x0521"[..];
|
let mut buf = &b"\x85\x92\x91"[..];
|
||||||
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
||||||
d.set_read_annotations(false);
|
d.set_read_annotations(false);
|
||||||
let v = d.demand_next().unwrap();
|
let v = d.demand_next().unwrap();
|
||||||
|
@ -268,117 +267,103 @@ mod decoder_tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn multiple_values_buf_advanced() {
|
#[test] fn multiple_values_buf_advanced() {
|
||||||
let mut buf = &b"\x81tPing\x81tPong"[..];
|
let mut buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
|
||||||
assert_eq!(buf.len(), 12);
|
assert_eq!(buf.len(), 16);
|
||||||
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
||||||
assert_eq!(d.reader.source.index, 0);
|
assert_eq!(d.reader.source.index, 0);
|
||||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
|
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
|
||||||
assert_eq!(d.reader.source.index, 6);
|
assert_eq!(d.reader.source.index, 8);
|
||||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
|
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
|
||||||
assert_eq!(d.reader.source.index, 12);
|
assert_eq!(d.reader.source.index, 16);
|
||||||
assert!(d.next().is_none());
|
assert!(d.next().is_none());
|
||||||
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
|
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"1").unwrap(), 1) }
|
#[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"0").unwrap(), 0) }
|
#[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"?").unwrap(), -1) }
|
#[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"A\xfe").unwrap(), -2) }
|
#[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"C\xff\xff\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"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
|
#[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
|
||||||
#[test] fn direct_i8_format_c() { assert_eq!(from_bytes::<i8>(b"$a\xfe\x04").unwrap(), -2) }
|
|
||||||
#[test] fn direct_i8_format_c_too_long() { assert_eq!(from_bytes::<i8>(b"$a\xffa\xfe\x04").unwrap(), -2) }
|
|
||||||
#[test] fn direct_i8_format_c_much_too_long() { assert_eq!(from_bytes::<i8>(b"$a\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xfe\x04").unwrap(), -2) }
|
|
||||||
|
|
||||||
#[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"1").unwrap(), 1) }
|
#[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"0").unwrap(), 0) }
|
#[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"A1").unwrap(), 49) }
|
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa01").unwrap(), 49) }
|
||||||
#[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"D\0\0\01").unwrap(), 49) }
|
#[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\01").unwrap(), 49) }
|
||||||
#[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"J\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"\xa9\0\0\0\0\0\0\0\0\01").unwrap(), 49) }
|
||||||
#[test] fn direct_u8_format_c() { assert_eq!(from_bytes::<u8>(b"$a1\x04").unwrap(), 49) }
|
|
||||||
#[test] fn direct_u8_format_c_too_long() { assert_eq!(from_bytes::<u8>(b"$a\0a1\x04").unwrap(), 49) }
|
|
||||||
#[test] fn direct_u8_format_c_much_too_long() { assert_eq!(from_bytes::<u8>(b"$a\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a1\x04").unwrap(), 49) }
|
|
||||||
|
|
||||||
#[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b">").unwrap(), -2) }
|
#[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"B\xfe\xff").unwrap(), -257) }
|
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa1\xfe\xff").unwrap(), -257) }
|
||||||
|
|
||||||
#[test] fn direct_u8_wrong_format() {
|
#[test] fn direct_u8_wrong_format() {
|
||||||
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"Ubogus"))
|
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xb1\x05bogus"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_u8_format_b_too_large() {
|
#[test] fn direct_u8_format_b_too_large() {
|
||||||
expect_number_out_of_range(from_bytes::<u8>(b"D\0\011"))
|
expect_number_out_of_range(from_bytes::<u8>(b"\xa3\0\011"))
|
||||||
}
|
|
||||||
|
|
||||||
#[test] fn direct_u8_format_c_too_large() {
|
|
||||||
expect_number_out_of_range(from_bytes::<u8>(b"$a1a1\x04"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_i8_format_b_too_large() {
|
#[test] fn direct_i8_format_b_too_large() {
|
||||||
expect_number_out_of_range(from_bytes::<i8>(b"B\xfe\xff"))
|
expect_number_out_of_range(from_bytes::<i8>(b"\xa1\xfe\xff"))
|
||||||
}
|
|
||||||
|
|
||||||
#[test] fn direct_i8_format_c_too_large() {
|
|
||||||
expect_number_out_of_range(from_bytes::<u8>(b"$a\xfea\xff\x04"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_i16_format_b_too_large() {
|
#[test] fn direct_i16_format_b_too_large() {
|
||||||
expect_number_out_of_range(from_bytes::<i16>(b"C\xfe\xff\xff"));
|
expect_number_out_of_range(from_bytes::<i16>(b"\xa2\xfe\xff\xff"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_i32_format_b_ok() {
|
#[test] fn direct_i32_format_b_ok() {
|
||||||
assert_eq!(from_bytes::<i32>(b"C\xfe\xff\xff").unwrap(), -65537);
|
assert_eq!(from_bytes::<i32>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_i32_format_b_ok_2() {
|
#[test] fn direct_i32_format_b_ok_2() {
|
||||||
assert_eq!(from_bytes::<i32>(b"D\xfe\xff\xff\xff").unwrap(), -16777217);
|
assert_eq!(from_bytes::<i32>(b"\xa3\xfe\xff\xff\xff").unwrap(), -16777217);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_i64_format_b() {
|
#[test] fn direct_i64_format_b() {
|
||||||
assert_eq!(from_bytes::<i64>(b"A\xff").unwrap(), -1);
|
assert_eq!(from_bytes::<i64>(b"\xa0\xff").unwrap(), -1);
|
||||||
assert_eq!(from_bytes::<i64>(b"C\xff\xff\xff").unwrap(), -1);
|
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xff\xff").unwrap(), -1);
|
||||||
assert_eq!(from_bytes::<i64>(b"J\xff\xff\xff\xff\xff\xff\xff\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"A\xfe").unwrap(), -2);
|
assert_eq!(from_bytes::<i64>(b"\xa0\xfe").unwrap(), -2);
|
||||||
assert_eq!(from_bytes::<i64>(b"C\xff\xfe\xff").unwrap(), -257);
|
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257);
|
||||||
assert_eq!(from_bytes::<i64>(b"C\xfe\xff\xff").unwrap(), -65537);
|
assert_eq!(from_bytes::<i64>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
|
||||||
assert_eq!(from_bytes::<i64>(b"J\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
|
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"J\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
|
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"J\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
|
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"I\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"I\x80\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"J\xff\x00\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"H\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
|
assert_eq!(from_bytes::<i64>(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
|
||||||
assert_eq!(from_bytes::<i64>(b"H\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
|
assert_eq!(from_bytes::<i64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
|
||||||
assert_eq!(from_bytes::<i64>(b"H\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
|
assert_eq!(from_bytes::<i64>(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
|
||||||
assert_eq!(from_bytes::<i64>(b"H\0\0\0\0\0\0\0\0").unwrap(), 0);
|
assert_eq!(from_bytes::<i64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
|
||||||
assert_eq!(from_bytes::<i64>(b"@").unwrap(), 0);
|
assert_eq!(from_bytes::<i64>(b"\x90").unwrap(), 0);
|
||||||
assert_eq!(from_bytes::<i64>(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
assert_eq!(from_bytes::<i64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn direct_u64_format_b() {
|
#[test] fn direct_u64_format_b() {
|
||||||
expect_number_out_of_range(from_bytes::<u64>(b"A\xff"));
|
expect_number_out_of_range(from_bytes::<u64>(b"\xa0\xff"));
|
||||||
assert_eq!(from_bytes::<u64>(b"B\0\xff").unwrap(), 255);
|
assert_eq!(from_bytes::<u64>(b"\xa1\0\xff").unwrap(), 255);
|
||||||
expect_number_out_of_range(from_bytes::<u64>(b"C\xff\xff\xff"));
|
expect_number_out_of_range(from_bytes::<u64>(b"\xa2\xff\xff\xff"));
|
||||||
assert_eq!(from_bytes::<u64>(b"D\0\xff\xff\xff").unwrap(), 0xffffff);
|
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff);
|
||||||
expect_number_out_of_range(from_bytes::<u64>(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
|
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"A\x02").unwrap(), 2);
|
assert_eq!(from_bytes::<u64>(b"\xa0\x02").unwrap(), 2);
|
||||||
assert_eq!(from_bytes::<u64>(b"C\x00\x01\x00").unwrap(), 256);
|
assert_eq!(from_bytes::<u64>(b"\xa2\x00\x01\x00").unwrap(), 256);
|
||||||
assert_eq!(from_bytes::<u64>(b"C\x01\x00\x00").unwrap(), 65536);
|
assert_eq!(from_bytes::<u64>(b"\xa2\x01\x00\x00").unwrap(), 65536);
|
||||||
assert_eq!(from_bytes::<u64>(b"J\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
|
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"J\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
|
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"J\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
|
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"J\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
|
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"J\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
|
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"I\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
|
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"I\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
|
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"J\x00\xff\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"H\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
|
assert_eq!(from_bytes::<u64>(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
|
||||||
assert_eq!(from_bytes::<u64>(b"H\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
|
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"H\x80\0\0\0\0\0\0\0"));
|
expect_number_out_of_range(from_bytes::<u64>(b"\xa7\x80\0\0\0\0\0\0\0"));
|
||||||
assert_eq!(from_bytes::<u64>(b"I\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
|
assert_eq!(from_bytes::<u64>(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
|
||||||
assert_eq!(from_bytes::<u64>(b"H\0\0\0\0\0\0\0\0").unwrap(), 0);
|
assert_eq!(from_bytes::<u64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
|
||||||
assert_eq!(from_bytes::<u64>(b"@").unwrap(), 0);
|
assert_eq!(from_bytes::<u64>(b"\x90").unwrap(), 0);
|
||||||
assert_eq!(from_bytes::<u64>(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
assert_eq!(from_bytes::<u64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,50 +427,54 @@ mod serde_tests {
|
||||||
assert_eq!(v, x);
|
assert_eq!(v, x);
|
||||||
|
|
||||||
let expected_bytes = vec![
|
let expected_bytes = vec![
|
||||||
0x8f, 0x10, // Struct, 15 members + 1 label
|
0xb4, // Struct
|
||||||
0x7b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
|
0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
|
||||||
0x55, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
|
0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
|
||||||
0x74, 0x73, 0x79, 0x6d, 0x31, // sym1
|
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1
|
||||||
0x74, 0x73, 0x79, 0x6d, 0x32, // sym2
|
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2
|
||||||
0x74, 0x73, 0x79, 0x6d, 0x33, // sym3
|
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3
|
||||||
0x74, 0x73, 0x79, 0x6d, 0x34, // sym4
|
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4
|
||||||
0x55, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
|
0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
|
||||||
0x65, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
|
0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
|
||||||
0x63, 0x76, 0x65, 0x63, // #"vec"
|
0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec"
|
||||||
0x94, // Sequence, 4 items
|
0xb5, // Sequence
|
||||||
0x0, // false
|
0x80, // false
|
||||||
0x1, // true
|
0x81, // true
|
||||||
0x0, // false
|
0x80, // false
|
||||||
0x1, // true
|
0x81, // true
|
||||||
0xa3, // Set, 3 items
|
0x84,
|
||||||
0x53, 0x6f, 0x6e, 0x65,
|
0xb6, // Set
|
||||||
0x55, 0x74, 0x68, 0x72, 0x65, 0x65,
|
0xb1, 0x03, 0x6f, 0x6e, 0x65,
|
||||||
0x53, 0x74, 0x77, 0x6f,
|
0xb1, 0x03, 0x74, 0x77, 0x6f,
|
||||||
0x42, 0x30, 0x39, // 12345
|
0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65,
|
||||||
0x52, 0x68, 0x69, // "hi"
|
0x84,
|
||||||
0xb6, // Dictionary, 6 items = 3 key/value pairs
|
0xa1, 0x30, 0x39, // 12345
|
||||||
0x54, 0x62, 0x6c, 0x75, 0x65, // "blue"
|
0xb1, 0x02, 0x68, 0x69, // "hi"
|
||||||
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x30, 0x42, 0x00, 0xff,
|
0xb7, // Dictionary
|
||||||
0x55, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green"
|
0xb1, 0x03, 0x72, 0x65, 0x64, // "red"
|
||||||
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x42, 0x00, 0xff, 0x30,
|
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84,
|
||||||
0x53, 0x72, 0x65, 0x64, // "red"
|
0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue"
|
||||||
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x42, 0x00, 0xff, 0x30, 0x30,
|
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,
|
||||||
|
|
||||||
0x2, 0x41, 0x45, 0x85, 0x1f, // 12.345,
|
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
|
||||||
0x3, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
|
0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
|
||||||
|
0x84,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let y = deserialize_from_bytes(&expected_bytes).unwrap();
|
||||||
|
println!("== y: {:#?}", &y);
|
||||||
|
assert_eq!(v, y);
|
||||||
|
|
||||||
let v_bytes_1 = PackedWriter::encode(&w).unwrap();
|
let v_bytes_1 = PackedWriter::encode(&w).unwrap();
|
||||||
println!("== w bytes = {:?}", v_bytes_1);
|
println!("== w bytes = {:?}", v_bytes_1);
|
||||||
assert_eq!(expected_bytes, v_bytes_1);
|
assert_eq!(expected_bytes, v_bytes_1);
|
||||||
|
|
||||||
let mut v_bytes_2 = Vec::new();
|
let mut v_bytes_2 = Vec::new();
|
||||||
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter(&mut v_bytes_2))).unwrap();
|
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
|
||||||
println!("== v bytes = {:?}", v_bytes_2);
|
println!("== v bytes = {:?}", v_bytes_2);
|
||||||
assert_eq!(v_bytes_1, v_bytes_2);
|
assert_eq!(v_bytes_1, v_bytes_2);
|
||||||
|
|
||||||
let y = deserialize_from_bytes(&v_bytes_1).unwrap();
|
|
||||||
println!("== y: {:#?}", &y);
|
|
||||||
assert_eq!(v, y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,42 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use super::value::writer::Writer;
|
use super::value::writer::{Writer, CompoundWriter};
|
||||||
|
|
||||||
pub use super::error::Error;
|
pub use super::error::Error;
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Serializer<'a, W: Writer> {
|
pub struct Serializer<'w, W: Writer> {
|
||||||
pub write: &'a mut W,
|
pub write: &'w mut W,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: Writer> Serializer<'a, W> {
|
impl<'w, W: Writer> Serializer<'w, W> {
|
||||||
pub fn new(write: &'a mut W) -> Self {
|
pub fn new(write: &'w mut W) -> Self {
|
||||||
Serializer { write }
|
Serializer { write }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SerializeCompound<'a, 'b, W: Writer> {
|
pub struct SerializeCompound<'a, 'w, W: Writer> {
|
||||||
ser: &'a mut Serializer<'b, W>,
|
ser: &'a mut Serializer<'w, W>,
|
||||||
c: W::Compound,
|
c: W::SeqWriter,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SerializeDictionary<'a, 'b, W: Writer> {
|
pub struct SerializeDictionary<'a, 'w, W: Writer> {
|
||||||
ser: &'a mut Serializer<'b, W>,
|
ser: &'a mut Serializer<'w, W>,
|
||||||
d: W::Dictionary,
|
d: W::SetWriter,
|
||||||
key_p: Option<W::KeyPointer>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type SerializeSeq = SerializeCompound<'a, 'b, W>;
|
type SerializeSeq = SerializeCompound<'a, 'w, W>;
|
||||||
type SerializeTuple = SerializeCompound<'a, 'b, W>;
|
type SerializeTuple = SerializeCompound<'a, 'w, W>;
|
||||||
type SerializeTupleStruct = SerializeCompound<'a, 'b, W>;
|
type SerializeTupleStruct = SerializeCompound<'a, 'w, W>;
|
||||||
type SerializeTupleVariant = SerializeCompound<'a, 'b, W>;
|
type SerializeTupleVariant = SerializeCompound<'a, 'w, W>;
|
||||||
type SerializeMap = SerializeDictionary<'a, 'b, W>;
|
type SerializeMap = SerializeDictionary<'a, 'w, W>;
|
||||||
type SerializeStruct = SerializeCompound<'a, 'b, W>;
|
type SerializeStruct = SerializeCompound<'a, 'w, W>;
|
||||||
type SerializeStructVariant = SerializeCompound<'a, 'b, W>;
|
type SerializeStructVariant = SerializeCompound<'a, 'w, W>;
|
||||||
|
|
||||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
|
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
|
||||||
Ok(self.write.write_bool(v)?)
|
Ok(self.write.write_bool(v)?)
|
||||||
|
@ -84,12 +83,14 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
||||||
let mut c = self.write.start_record(1)?;
|
let mut c = self.write.start_record(Some(1))?;
|
||||||
let p = self.write.write_symbol("UnicodeScalar")?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol("UnicodeScalar")?;
|
||||||
let p = self.write.write_u32(v as u32)?;
|
c.delimit()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.extend()?;
|
||||||
Ok(self.write.end_compound(c)?)
|
c.write_u32(v as u32)?;
|
||||||
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
||||||
|
@ -101,33 +102,38 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_none(self) -> Result<Self::Ok> {
|
fn serialize_none(self) -> Result<Self::Ok> {
|
||||||
let mut c = self.write.start_record(0)?;
|
let mut c = self.write.start_record(Some(0))?;
|
||||||
let p = self.write.write_symbol("None")?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol("None")?;
|
||||||
Ok(self.write.end_compound(c)?)
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
|
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
|
||||||
let mut c = self.write.start_record(1)?;
|
let mut c = self.write.start_record(Some(1))?;
|
||||||
let p = self.write.write_symbol("Some")?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol("Some")?;
|
||||||
let p = v.serialize(&mut *self)?;
|
c.delimit()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.extend()?;
|
||||||
Ok(self.write.end_compound(c)?)
|
to_writer(&mut c, v)?;
|
||||||
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit(self) -> Result<Self::Ok> {
|
fn serialize_unit(self) -> Result<Self::Ok> {
|
||||||
let mut c = self.write.start_record(0)?;
|
let mut c = self.write.start_record(Some(0))?;
|
||||||
let p = self.write.write_symbol("tuple")?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol("tuple")?;
|
||||||
Ok(self.write.end_compound(c)?)
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
|
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
|
||||||
let mut c = self.write.start_record(0)?;
|
let mut c = self.write.start_record(Some(0))?;
|
||||||
let p = self.write.write_symbol(name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(name)?;
|
||||||
Ok(self.write.end_compound(c)?)
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit_variant(self,
|
fn serialize_unit_variant(self,
|
||||||
|
@ -136,27 +142,28 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
||||||
variant_name: &'static str) ->
|
variant_name: &'static str) ->
|
||||||
Result<Self::Ok>
|
Result<Self::Ok>
|
||||||
{
|
{
|
||||||
let mut c = self.write.start_record(0)?;
|
let mut c = self.write.start_record(Some(0))?;
|
||||||
let p = self.write.write_symbol(variant_name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(variant_name)?;
|
||||||
Ok(self.write.end_compound(c)?)
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
|
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
|
||||||
Result<Self::Ok> where T: Serialize
|
Result<Self::Ok> where T: Serialize
|
||||||
{
|
{
|
||||||
match super::value::magic::receive_output_value(name, value) {
|
match super::value::magic::receive_output_value(name, value) {
|
||||||
Some(v) => {
|
Some(v) => Ok(self.write.write(&v)?),
|
||||||
Ok(self.write.write(&v)?)
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
|
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
|
||||||
let mut c = self.write.start_record(1)?;
|
let mut c = self.write.start_record(Some(1))?;
|
||||||
let p = self.write.write_symbol(name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(name)?;
|
||||||
let p = value.serialize(&mut *self)?;
|
c.delimit()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.extend()?;
|
||||||
Ok(self.write.end_compound(c)?)
|
to_writer(&mut c, value)?;
|
||||||
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,38 +175,36 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
||||||
value: &T) ->
|
value: &T) ->
|
||||||
Result<Self::Ok> where T: Serialize
|
Result<Self::Ok> where T: Serialize
|
||||||
{
|
{
|
||||||
let mut c = self.write.start_record(1)?;
|
let mut c = self.write.start_record(Some(1))?;
|
||||||
let p = self.write.write_symbol(variant_name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(variant_name)?;
|
||||||
let p = value.serialize(&mut *self)?;
|
c.delimit()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.extend()?;
|
||||||
Ok(self.write.end_compound(c)?)
|
to_writer(&mut c, value)?;
|
||||||
|
c.delimit()?;
|
||||||
|
Ok(self.write.end_seq(c)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
|
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||||
let c = match count {
|
let c = self.write.start_sequence(count)?;
|
||||||
Some(n) => self.write.start_sequence(n)?,
|
|
||||||
None => match self.write.stream_sequence()? {
|
|
||||||
Some(c) => c,
|
|
||||||
None => return Err(Error::StreamingSerializationUnsupported),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(SerializeCompound { ser: self, c })
|
Ok(SerializeCompound { ser: self, c })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
|
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
|
||||||
let mut c = self.write.start_record(count)?;
|
let mut c = self.write.start_record(Some(count))?;
|
||||||
let p = self.write.write_symbol("tuple")?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol("tuple")?;
|
||||||
|
c.delimit()?;
|
||||||
Ok(SerializeCompound { ser: self, c })
|
Ok(SerializeCompound { ser: self, c })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
|
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
|
||||||
Result<Self::SerializeTupleStruct>
|
Result<Self::SerializeTupleStruct>
|
||||||
{
|
{
|
||||||
let mut c = self.write.start_record(count)?;
|
let mut c = self.write.start_record(Some(count))?;
|
||||||
let p = self.write.write_symbol(name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(name)?;
|
||||||
|
c.delimit()?;
|
||||||
Ok(SerializeCompound { ser: self, c })
|
Ok(SerializeCompound { ser: self, c })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,27 +215,23 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
||||||
count: usize) ->
|
count: usize) ->
|
||||||
Result<Self::SerializeTupleVariant>
|
Result<Self::SerializeTupleVariant>
|
||||||
{
|
{
|
||||||
let mut c = self.write.start_record(count)?;
|
let mut c = self.write.start_record(Some(count))?;
|
||||||
let p = self.write.write_symbol(variant_name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(variant_name)?;
|
||||||
|
c.delimit()?;
|
||||||
Ok(SerializeCompound { ser: self, c })
|
Ok(SerializeCompound { ser: self, c })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
|
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
|
||||||
let d = match count {
|
let d = self.write.start_dictionary(count)?;
|
||||||
Some(n) => self.write.start_dictionary(n)?,
|
Ok(SerializeDictionary { ser: self, d })
|
||||||
None => match self.write.stream_dictionary()? {
|
|
||||||
Some(d) => d,
|
|
||||||
None => return Err(Error::StreamingSerializationUnsupported),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(SerializeDictionary { ser: self, d, key_p: None })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
|
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
|
||||||
let mut c = self.write.start_record(count)?;
|
let mut c = self.write.start_record(Some(count))?;
|
||||||
let p = self.write.write_symbol(name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(name)?;
|
||||||
|
c.delimit()?;
|
||||||
Ok(SerializeCompound { ser: self, c })
|
Ok(SerializeCompound { ser: self, c })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,122 +242,130 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
||||||
count: usize) ->
|
count: usize) ->
|
||||||
Result<Self::SerializeStructVariant>
|
Result<Self::SerializeStructVariant>
|
||||||
{
|
{
|
||||||
let mut c = self.write.start_record(count)?;
|
let mut c = self.write.start_record(Some(count))?;
|
||||||
let p = self.write.write_symbol(variant_name)?;
|
c.extend()?;
|
||||||
self.write.extend_compound(&mut c, p)?;
|
c.write_symbol(variant_name)?;
|
||||||
|
c.delimit()?;
|
||||||
Ok(SerializeCompound { ser: self, c })
|
Ok(SerializeCompound { ser: self, c })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
|
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
|
||||||
let kp1 = key.serialize(&mut *self.ser)?;
|
self.d.extend()?;
|
||||||
self.key_p = Some(self.ser.write.extend_dictionary_key(&mut self.d, kp1)?);
|
to_writer(&mut self.d, key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
||||||
let vp1 = value.serialize(&mut *self.ser)?;
|
to_writer(&mut self.d, value)?;
|
||||||
Ok(self.ser.write.extend_dictionary_value(&mut self.d, self.key_p.take().unwrap(), vp1)?)
|
Ok(self.d.delimit()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_dictionary(self.d)?)
|
Ok(self.ser.write.end_set(self.d)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
fn extend<T: ?Sized>(&mut self, value: &T) -> Result<()>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
|
self.c.extend()?;
|
||||||
|
to_writer(&mut self.c, value)?;
|
||||||
|
Ok(self.c.delimit()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn complete(self) -> Result<()> {
|
||||||
|
Ok(self.ser.write.end_seq(self.c)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'w, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'w, W> {
|
||||||
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
|
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
|
||||||
where T: Serialize
|
where T: Serialize
|
||||||
{
|
{
|
||||||
let p = value.serialize(&mut *self.ser)?;
|
self.extend(value)
|
||||||
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_compound(self.c)?)
|
self.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
|
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
|
||||||
where T: Serialize
|
where T: Serialize
|
||||||
{
|
{
|
||||||
let p = value.serialize(&mut *self.ser)?;
|
self.extend(value)
|
||||||
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_compound(self.c)?)
|
self.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
||||||
let p = value.serialize(&mut *self.ser)?;
|
self.extend(value)
|
||||||
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_compound(self.c)?)
|
self.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
||||||
let p = value.serialize(&mut *self.ser)?;
|
self.extend(value)
|
||||||
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_compound(self.c)?)
|
self.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
||||||
let p = value.serialize(&mut *self.ser)?;
|
self.extend(value)
|
||||||
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_compound(self.c)?)
|
self.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'b, W> {
|
impl<'a, 'w, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'w, W> {
|
||||||
type Ok = W::Pointer;
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
|
||||||
let p = value.serialize(&mut *self.ser)?;
|
self.extend(value)
|
||||||
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
Ok(self.ser.write.end_compound(self.c)?)
|
self.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_writer<W: Writer, T: Serialize>(write: &mut W, value: &T) -> Result<W::Pointer> {
|
pub fn to_writer<W: Writer, T: Serialize + ?Sized>(write: &mut W, value: &T) -> Result<()> {
|
||||||
let mut ser: Serializer<'_, W> = Serializer::new(write);
|
Ok(value.serialize(&mut Serializer::new(write))?)
|
||||||
value.serialize(&mut ser)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,86 @@
|
||||||
use std::convert::{TryFrom, From};
|
use std::convert::{TryFrom, From};
|
||||||
use num_enum::TryFromPrimitive;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Op {
|
pub enum Tag {
|
||||||
Misc(u8),
|
False,
|
||||||
Atom(AtomMinor),
|
True,
|
||||||
Compound(CompoundMinor),
|
Float,
|
||||||
Reserved(u8),
|
Double,
|
||||||
|
End,
|
||||||
|
Annotation,
|
||||||
|
SmallInteger(i8),
|
||||||
|
MediumInteger(u8),
|
||||||
|
SignedInteger,
|
||||||
|
String,
|
||||||
|
ByteString,
|
||||||
|
Symbol,
|
||||||
|
Record,
|
||||||
|
Sequence,
|
||||||
|
Set,
|
||||||
|
Dictionary,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct InvalidOp;
|
pub struct InvalidTag(u8);
|
||||||
|
|
||||||
impl From<InvalidOp> for std::io::Error {
|
impl From<InvalidTag> for std::io::Error {
|
||||||
fn from(_v: InvalidOp) -> Self {
|
fn from(v: InvalidTag) -> Self {
|
||||||
std::io::Error::new(std::io::ErrorKind::InvalidData,
|
std::io::Error::new(std::io::ErrorKind::InvalidData,
|
||||||
"Invalid Preserves lead byte major value")
|
format!("Invalid Preserves tag {}", v.0).to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<InvalidOp> for crate::error::Error {
|
impl From<InvalidTag> for crate::error::Error {
|
||||||
fn from(v: InvalidOp) -> Self {
|
fn from(v: InvalidTag) -> Self {
|
||||||
crate::error::Error::Io(v.into())
|
crate::error::Error::Io(v.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u8> for Op {
|
impl TryFrom<u8> for Tag {
|
||||||
type Error = InvalidOp;
|
type Error = InvalidTag;
|
||||||
fn try_from(v: u8) -> Result<Self, Self::Error> {
|
fn try_from(v: u8) -> Result<Self, Self::Error> {
|
||||||
match v >> 2 {
|
|
||||||
0 => Ok(Self::Misc(v & 3)),
|
|
||||||
1 => Ok(Self::Atom(AtomMinor::try_from(v & 3).unwrap())),
|
|
||||||
2 => Ok(Self::Compound(CompoundMinor::try_from(v & 3).unwrap())),
|
|
||||||
3 => Ok(Self::Reserved(v & 3)),
|
|
||||||
_ => Err(InvalidOp),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Op> for u8 {
|
|
||||||
fn from(v: Op) -> Self {
|
|
||||||
match v {
|
match v {
|
||||||
Op::Misc(minor) => minor & 3,
|
0x80 => Ok(Self::False),
|
||||||
Op::Atom(minor) => (1 << 2) | ((minor as u8) & 3),
|
0x81 => Ok(Self::True),
|
||||||
Op::Compound(minor) => (2 << 2) | ((minor as u8) & 3),
|
0x82 => Ok(Self::Float),
|
||||||
Op::Reserved(minor) => (3 << 2) | (minor & 3),
|
0x83 => Ok(Self::Double),
|
||||||
|
0x84 => Ok(Self::End),
|
||||||
|
0x85 => Ok(Self::Annotation),
|
||||||
|
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),
|
||||||
|
_ => Err(InvalidTag(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)]
|
impl From<Tag> for u8 {
|
||||||
#[repr(u8)]
|
fn from(v: Tag) -> Self {
|
||||||
pub enum AtomMinor {
|
match v {
|
||||||
SignedInteger = 0,
|
Tag::False => 0x80,
|
||||||
String = 1,
|
Tag::True => 0x81,
|
||||||
ByteString = 2,
|
Tag::Float => 0x82,
|
||||||
Symbol = 3,
|
Tag::Double => 0x83,
|
||||||
}
|
Tag::End => 0x84,
|
||||||
|
Tag::Annotation => 0x85,
|
||||||
#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)]
|
Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 },
|
||||||
#[repr(u8)]
|
Tag::MediumInteger(count) => count - 1 + 0xa0,
|
||||||
pub enum CompoundMinor {
|
Tag::SignedInteger => 0xb0,
|
||||||
Record = 0,
|
Tag::String => 0xb1,
|
||||||
Sequence = 1,
|
Tag::ByteString => 0xb2,
|
||||||
Set = 2,
|
Tag::Symbol => 0xb3,
|
||||||
Dictionary = 3,
|
Tag::Record => 0xb4,
|
||||||
|
Tag::Sequence => 0xb5,
|
||||||
|
Tag::Set => 0xb6,
|
||||||
|
Tag::Dictionary => 0xb7,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,10 @@ use std::marker::PhantomData;
|
||||||
use super::super::signed_integer::SignedInteger;
|
use super::super::signed_integer::SignedInteger;
|
||||||
use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations};
|
use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations};
|
||||||
|
|
||||||
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
|
use super::constants::Tag;
|
||||||
use super::super::reader::{
|
use super::super::reader::{
|
||||||
BinarySource,
|
BinarySource,
|
||||||
BytesBinarySource,
|
BytesBinarySource,
|
||||||
CompoundBody,
|
|
||||||
CompoundLimit,
|
|
||||||
ConfiguredReader,
|
ConfiguredReader,
|
||||||
IOBinarySource,
|
IOBinarySource,
|
||||||
IOResult,
|
IOResult,
|
||||||
|
@ -87,16 +85,8 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wirelength(&mut self, arg: u8) -> IOResult<usize> {
|
|
||||||
if arg < 15 {
|
|
||||||
Ok(usize::from(arg))
|
|
||||||
} else {
|
|
||||||
self.varint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn peekend(&mut self) -> IOResult<bool> {
|
fn peekend(&mut self) -> IOResult<bool> {
|
||||||
if self.peek()? == 4 {
|
if self.peek()? == Tag::End.into() {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,28 +94,10 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_chunks(&mut self) -> IOResult<Vec<u8>> {
|
fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
|
||||||
let mut bs = Vec::with_capacity(256);
|
|
||||||
while !self.peekend()? {
|
|
||||||
match decodeop(self.peek()?)? {
|
|
||||||
(Op::Atom(AtomMinor::ByteString), arg) => {
|
|
||||||
self.skip()?;
|
|
||||||
let count = self.wirelength(arg)?;
|
|
||||||
if count == 0 {
|
|
||||||
return Err(io_syntax_error("Empty binary chunks are forbidden"));
|
|
||||||
}
|
|
||||||
bs.extend_from_slice(&self.readbytes(count)?)
|
|
||||||
},
|
|
||||||
_ => return Err(io_syntax_error("Unexpected non-format-B-ByteString chunk"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(bs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn peek_next_nonannotation_op(&mut self) -> ReaderResult<(Op, u8)> {
|
|
||||||
loop {
|
loop {
|
||||||
match decodeop(self.peek()?)? {
|
match Tag::try_from(self.peek()?)? {
|
||||||
(Op::Misc(0), 5) => {
|
Tag::Annotation => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
self.skip_value()?;
|
self.skip_value()?;
|
||||||
},
|
},
|
||||||
|
@ -134,44 +106,29 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_atomic(&mut self, minor: AtomMinor, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> {
|
fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> {
|
||||||
match self.peek_next_nonannotation_op()? {
|
let actual_tag = self.peek_next_nonannotation_tag()?;
|
||||||
(Op::Atom(actual_minor), arg) if actual_minor == minor => {
|
if actual_tag == expected_tag {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let count = self.wirelength(arg)?;
|
let count = self.varint()?;
|
||||||
Ok(self.readbytes(count)?)
|
Ok(self.readbytes(count)?)
|
||||||
}
|
} else {
|
||||||
(Op::Misc(2), arg) => match Op::try_from(arg)? {
|
Err(self.expected(k))
|
||||||
Op::Atom(actual_minor) if actual_minor == minor => {
|
|
||||||
self.skip()?;
|
|
||||||
Ok(Cow::Owned(self.gather_chunks()?))
|
|
||||||
}
|
|
||||||
_ => Err(self.expected(k)),
|
|
||||||
},
|
|
||||||
_ => Err(self.expected(k)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_compound(&mut self, minor: CompoundMinor, k: ExpectedKind) ->
|
fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()>
|
||||||
ReaderResult<CompoundBody<CompoundMinor>>
|
|
||||||
{
|
{
|
||||||
match self.peek_next_nonannotation_op()? {
|
let actual_tag = self.peek_next_nonannotation_tag()?;
|
||||||
(Op::Compound(actual_minor), arg) if actual_minor == minor => {
|
if actual_tag == expected_tag {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
Ok(CompoundBody::counted(minor, self.wirelength(arg)?))
|
Ok(())
|
||||||
}
|
} else {
|
||||||
(Op::Misc(2), arg) => match Op::try_from(arg)? {
|
Err(self.expected(k))
|
||||||
Op::Compound(actual_minor) if actual_minor == minor => {
|
|
||||||
self.skip()?;
|
|
||||||
Ok(CompoundBody::streaming(minor))
|
|
||||||
}
|
|
||||||
_ => Err(self.expected(k)),
|
|
||||||
},
|
|
||||||
_ => Err(self.expected(k)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_number_format_b(&mut self, count: usize) -> IOResult<SignedInteger> {
|
fn read_signed_integer(&mut self, count: usize) -> IOResult<SignedInteger> {
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return Ok(SignedInteger::from(0 as i128));
|
return Ok(SignedInteger::from(0 as i128));
|
||||||
}
|
}
|
||||||
|
@ -211,28 +168,30 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
|
||||||
where
|
where
|
||||||
F: FnOnce(u128) -> Option<T>
|
F: FnOnce(u128) -> Option<T>
|
||||||
{
|
{
|
||||||
match self.peek_next_nonannotation_op()? {
|
let tag = self.peek_next_nonannotation_tag()?;
|
||||||
(Op::Misc(3), arg) => {
|
match tag {
|
||||||
|
Tag::SmallInteger(v) => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
if arg > 12 {
|
if v < 0 {
|
||||||
Err(out_of_range((arg as i8) - 16))
|
Err(out_of_range(v))
|
||||||
} else {
|
} else {
|
||||||
f(arg as u128).ok_or_else(|| out_of_range(arg))
|
f(v as u128).ok_or_else(|| out_of_range(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Op::Atom(AtomMinor::SignedInteger), arg) => {
|
Tag::MediumInteger(count) => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let count = self.wirelength(arg)?;
|
let n = &self.read_signed_integer(count.into())?;
|
||||||
let n = &self.read_number_format_b(count)?;
|
|
||||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||||
f(i).ok_or_else(|| out_of_range(i))
|
f(i).ok_or_else(|| out_of_range(i))
|
||||||
}
|
}
|
||||||
_ => {
|
Tag::SignedInteger => {
|
||||||
let n_value = self.demand_next(false)?;
|
self.skip()?;
|
||||||
let n = n_value.value().to_signedinteger()?;
|
let count = self.varint()?;
|
||||||
|
let n = &self.read_signed_integer(count)?;
|
||||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||||
f(i).ok_or_else(|| out_of_range(i))
|
f(i).ok_or_else(|| out_of_range(i))
|
||||||
}
|
}
|
||||||
|
_ => Err(self.expected(ExpectedKind::SignedInteger))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,166 +199,169 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
|
||||||
where
|
where
|
||||||
F: FnOnce(i128) -> Option<T>
|
F: FnOnce(i128) -> Option<T>
|
||||||
{
|
{
|
||||||
match self.peek_next_nonannotation_op()? {
|
let tag = self.peek_next_nonannotation_tag()?;
|
||||||
(Op::Misc(3), arg) => {
|
match tag {
|
||||||
|
Tag::SmallInteger(v) => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let n = arg as i128;
|
f(v.into()).ok_or_else(|| out_of_range(v))
|
||||||
let n = if n > 12 { n - 16 } else { n };
|
|
||||||
f(n).ok_or_else(|| out_of_range(n))
|
|
||||||
}
|
}
|
||||||
(Op::Atom(AtomMinor::SignedInteger), arg) => {
|
Tag::MediumInteger(count) => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let count = self.wirelength(arg)?;
|
let n = &self.read_signed_integer(count.into())?;
|
||||||
let n = &self.read_number_format_b(count)?;
|
|
||||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||||
f(i).ok_or_else(|| out_of_range(i))
|
f(i).ok_or_else(|| out_of_range(i))
|
||||||
}
|
}
|
||||||
_ => {
|
Tag::SignedInteger => {
|
||||||
let n_value = self.demand_next(false)?;
|
self.skip()?;
|
||||||
let n = n_value.value().to_signedinteger()?;
|
let count = self.varint()?;
|
||||||
|
let n = &self.read_signed_integer(count)?;
|
||||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||||
f(i).ok_or_else(|| out_of_range(i))
|
f(i).ok_or_else(|| out_of_range(i))
|
||||||
}
|
}
|
||||||
|
_ => Err(self.expected(ExpectedKind::SignedInteger))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
||||||
type CompoundInfo = CompoundMinor;
|
|
||||||
|
|
||||||
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
|
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Err(e) if is_eof_io_error(&e) => return Ok(None),
|
Err(e) if is_eof_io_error(&e) => return Ok(None),
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
}
|
}
|
||||||
loop {
|
Ok(Some(match Tag::try_from(self.read()?)? {
|
||||||
return Ok(Some(match decodeop(self.read()?)? {
|
Tag::False => FALSE.clone(),
|
||||||
(Op::Misc(0), 0) => FALSE.clone(),
|
Tag::True => TRUE.clone(),
|
||||||
(Op::Misc(0), 1) => TRUE.clone(),
|
Tag::Float => {
|
||||||
(Op::Misc(0), 2) => {
|
let mut bs = [0; 4];
|
||||||
let mut bs = [0; 4];
|
self.readbytes_into(&mut bs)?;
|
||||||
self.readbytes_into(&mut bs)?;
|
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
|
||||||
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
|
}
|
||||||
}
|
Tag::Double => {
|
||||||
(Op::Misc(0), 3) => {
|
let mut bs = [0; 8];
|
||||||
let mut bs = [0; 8];
|
self.readbytes_into(&mut bs)?;
|
||||||
self.readbytes_into(&mut bs)?;
|
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
|
||||||
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
|
}
|
||||||
}
|
Tag::Annotation => {
|
||||||
(Op::Misc(0), 5) => {
|
if read_annotations {
|
||||||
if read_annotations {
|
let mut annotations = vec![self.demand_next(read_annotations)?];
|
||||||
let mut annotations = vec![self.demand_next(read_annotations)?];
|
while Tag::try_from(self.peek()?)? == Tag::Annotation {
|
||||||
while decodeop(self.peek()?)? == (Op::Misc(0), 5) {
|
self.skip()?;
|
||||||
self.skip()?;
|
annotations.push(self.demand_next(read_annotations)?);
|
||||||
annotations.push(self.demand_next(read_annotations)?);
|
|
||||||
}
|
|
||||||
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
|
|
||||||
annotations.extend_from_slice(existing_annotations.slice());
|
|
||||||
IOValue::wrap(Annotations::new(Some(annotations)), v)
|
|
||||||
} else {
|
|
||||||
self.skip_value()?;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
|
||||||
(Op::Misc(0), _) => Err(io_syntax_error("Invalid format A encoding"))?,
|
annotations.extend_from_slice(existing_annotations.slice());
|
||||||
(Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?,
|
IOValue::wrap(Annotations::new(Some(annotations)), v)
|
||||||
(Op::Misc(2), arg) => match Op::try_from(arg)? {
|
} else {
|
||||||
Op::Atom(minor) =>
|
self.skip_value()?;
|
||||||
decodebinary(minor, Cow::Owned(self.gather_chunks()?))?,
|
while Tag::try_from(self.peek()?)? == Tag::Annotation {
|
||||||
Op::Compound(minor) => decodecompound(minor, DelimitedStream {
|
self.skip()?;
|
||||||
reader: self.configured(read_annotations),
|
self.skip_value()?;
|
||||||
})?,
|
}
|
||||||
_ => Err(io_syntax_error("Invalid format C start byte"))?,
|
self.demand_next(read_annotations)?
|
||||||
}
|
|
||||||
(Op::Misc(3), arg) => {
|
|
||||||
let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) };
|
|
||||||
// TODO: prebuild these in value.rs
|
|
||||||
Value::from(n).wrap()
|
|
||||||
}
|
|
||||||
(Op::Misc(_), _) => unreachable!(),
|
|
||||||
(Op::Atom(AtomMinor::SignedInteger), arg) => {
|
|
||||||
let count = self.wirelength(arg)?;
|
|
||||||
let n = self.read_number_format_b(count)?;
|
|
||||||
Value::SignedInteger(n).wrap()
|
|
||||||
}
|
|
||||||
(Op::Atom(minor), arg) => {
|
|
||||||
let count = self.wirelength(arg)?;
|
|
||||||
decodebinary(minor, self.readbytes(count)?)?
|
|
||||||
}
|
|
||||||
(Op::Compound(minor), arg) => {
|
|
||||||
let count = self.wirelength(arg)?;
|
|
||||||
decodecompound(minor, CountedStream {
|
|
||||||
reader: self.configured(read_annotations),
|
|
||||||
count,
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
(Op::Reserved(3), 15) => continue,
|
|
||||||
(Op::Reserved(_), _) => return Err(InvalidOp.into()),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
|
||||||
if let Some(expected_arity) = arity {
|
|
||||||
let compound_format =
|
|
||||||
self.next_compound(CompoundMinor::Record, ExpectedKind::Record(arity))?;
|
|
||||||
if let CompoundLimit::Counted(count) = compound_format.limit {
|
|
||||||
if count != expected_arity + 1 /* we add 1 for the label */ {
|
|
||||||
return Err(error::Error::Expected(ExpectedKind::Record(arity),
|
|
||||||
Received::ReceivedSomethingElse));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(compound_format)
|
Tag::SmallInteger(v) => {
|
||||||
} else {
|
// TODO: prebuild these in value.rs
|
||||||
self.next_compound(CompoundMinor::Record, ExpectedKind::Record(None))
|
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 iter = DelimitedStream { reader: self.configured(read_annotations) };
|
||||||
|
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
|
||||||
|
if vs.len() < 1 {
|
||||||
|
return Err(io_syntax_error("Too few elements in encoded record"))
|
||||||
|
}
|
||||||
|
Value::Record(Record(vs)).wrap()
|
||||||
|
}
|
||||||
|
Tag::Sequence => {
|
||||||
|
let iter = DelimitedStream { reader: self.configured(read_annotations) };
|
||||||
|
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
|
||||||
|
Value::Sequence(vs).wrap()
|
||||||
|
}
|
||||||
|
Tag::Set => {
|
||||||
|
let iter = DelimitedStream { reader: self.configured(read_annotations) };
|
||||||
|
let mut s = Set::new();
|
||||||
|
for res in iter { s.insert(res?); }
|
||||||
|
Value::Set(s).wrap()
|
||||||
|
}
|
||||||
|
Tag::Dictionary => {
|
||||||
|
let mut iter = DelimitedStream { reader: self.configured(read_annotations) };
|
||||||
|
let mut d = Map::new();
|
||||||
|
while let Some(kres) = iter.next() {
|
||||||
|
let k = kres?;
|
||||||
|
match iter.next() {
|
||||||
|
Some(vres) => {
|
||||||
|
let v = vres?;
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()> {
|
||||||
match self.peek_next_nonannotation_op()? {
|
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
|
||||||
(Op::Compound(minor), arg)
|
self.ensure_more_expected()
|
||||||
if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => {
|
}
|
||||||
self.skip()?;
|
|
||||||
Ok(CompoundBody::counted(minor, self.wirelength(arg)?))
|
fn open_sequence_or_set(&mut self) -> ReaderResult<()> {
|
||||||
}
|
match self.peek_next_nonannotation_tag()? {
|
||||||
(Op::Misc(2), arg) => match Op::try_from(arg)? {
|
Tag::Sequence | Tag::Set => {
|
||||||
Op::Compound(minor)
|
self.skip()?;
|
||||||
if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => {
|
Ok(())
|
||||||
self.skip()?;
|
|
||||||
Ok(CompoundBody::streaming(minor))
|
|
||||||
}
|
|
||||||
_ => Err(self.expected(ExpectedKind::SequenceOrSet)),
|
|
||||||
}
|
}
|
||||||
_ => Err(self.expected(ExpectedKind::SequenceOrSet)),
|
_ => Err(self.expected(ExpectedKind::SequenceOrSet)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
fn open_sequence(&mut self) -> ReaderResult<()> {
|
||||||
self.next_compound(CompoundMinor::Sequence, ExpectedKind::Sequence)
|
self.next_compound(Tag::Sequence, ExpectedKind::Sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
fn open_set(&mut self) -> ReaderResult<()> {
|
||||||
self.next_compound(CompoundMinor::Set, ExpectedKind::Set)
|
self.next_compound(Tag::Set, ExpectedKind::Set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
fn open_dictionary(&mut self) -> ReaderResult<()> {
|
||||||
self.next_compound(CompoundMinor::Dictionary, ExpectedKind::Dictionary)
|
self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_compound_counted(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<()> {
|
fn close_compound(&mut self) -> ReaderResult<bool> {
|
||||||
// Nothing to do -- no close delimiter to consume
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn close_compound_stream(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<bool> {
|
|
||||||
Ok(self.peekend()?)
|
Ok(self.peekend()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_boolean(&mut self) -> ReaderResult<bool> {
|
fn next_boolean(&mut self) -> ReaderResult<bool> {
|
||||||
match self.peek_next_nonannotation_op()? {
|
match self.peek_next_nonannotation_tag()? {
|
||||||
(Op::Misc(0), 0) => { self.skip()?; Ok(false) }
|
Tag::False => { self.skip()?; Ok(false) }
|
||||||
(Op::Misc(0), 1) => { self.skip()?; Ok(true) }
|
Tag::True => { self.skip()?; Ok(true) }
|
||||||
_ => Err(self.expected(ExpectedKind::Boolean)),
|
_ => Err(self.expected(ExpectedKind::Boolean)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,14 +379,14 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
||||||
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
|
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
|
||||||
|
|
||||||
fn next_float(&mut self) -> ReaderResult<f32> {
|
fn next_float(&mut self) -> ReaderResult<f32> {
|
||||||
match self.peek_next_nonannotation_op()? {
|
match self.peek_next_nonannotation_tag()? {
|
||||||
(Op::Misc(0), 2) => {
|
Tag::Float => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let mut bs = [0; 4];
|
let mut bs = [0; 4];
|
||||||
self.readbytes_into(&mut bs)?;
|
self.readbytes_into(&mut bs)?;
|
||||||
Ok(f32::from_bits(u32::from_be_bytes(bs)))
|
Ok(f32::from_bits(u32::from_be_bytes(bs)))
|
||||||
},
|
},
|
||||||
(Op::Misc(0), 3) => {
|
Tag::Double => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let mut bs = [0; 8];
|
let mut bs = [0; 8];
|
||||||
self.readbytes_into(&mut bs)?;
|
self.readbytes_into(&mut bs)?;
|
||||||
|
@ -435,14 +397,14 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_double(&mut self) -> ReaderResult<f64> {
|
fn next_double(&mut self) -> ReaderResult<f64> {
|
||||||
match self.peek_next_nonannotation_op()? {
|
match self.peek_next_nonannotation_tag()? {
|
||||||
(Op::Misc(0), 2) => {
|
Tag::Float => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let mut bs = [0; 4];
|
let mut bs = [0; 4];
|
||||||
self.readbytes_into(&mut bs)?;
|
self.readbytes_into(&mut bs)?;
|
||||||
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
|
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
|
||||||
},
|
},
|
||||||
(Op::Misc(0), 3) => {
|
Tag::Double => {
|
||||||
self.skip()?;
|
self.skip()?;
|
||||||
let mut bs = [0; 8];
|
let mut bs = [0; 8];
|
||||||
self.readbytes_into(&mut bs)?;
|
self.readbytes_into(&mut bs)?;
|
||||||
|
@ -453,30 +415,15 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
|
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
|
||||||
Ok(decodestr(self.next_atomic(AtomMinor::String, ExpectedKind::Symbol)?)?)
|
Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
|
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
|
||||||
self.next_atomic(AtomMinor::ByteString, ExpectedKind::Symbol)
|
self.next_atomic(Tag::ByteString, ExpectedKind::Symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
|
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
|
||||||
Ok(decodestr(self.next_atomic(AtomMinor::Symbol, ExpectedKind::Symbol)?)?)
|
Ok(decodestr(self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?)?)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CountedStream<'de, R: Reader<'de>> {
|
|
||||||
reader: ConfiguredReader<'de, R>,
|
|
||||||
count: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, R: Reader<'de>> Iterator for CountedStream<'de, R>
|
|
||||||
{
|
|
||||||
type Item = IOResult<IOValue>;
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.count == 0 { return None }
|
|
||||||
self.count -= 1;
|
|
||||||
Some(self.reader.reader.demand_next(self.reader.read_annotations))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,11 +443,7 @@ impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decodeop(b: u8) -> IOResult<(Op, u8)> {
|
fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
|
||||||
Ok((Op::try_from(b >> 4)?, b & 15))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
|
|
||||||
match cow {
|
match cow {
|
||||||
Cow::Borrowed(bs) =>
|
Cow::Borrowed(bs) =>
|
||||||
Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)),
|
Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)),
|
||||||
|
@ -508,53 +451,3 @@ pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
|
||||||
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?.to_owned())),
|
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decodebinary<'de>(minor: AtomMinor, bs: Cow<'de, [u8]>) -> IOResult<IOValue> {
|
|
||||||
Ok(match minor {
|
|
||||||
AtomMinor::SignedInteger => Value::from(&BigInt::from_signed_bytes_be(&bs)).wrap(),
|
|
||||||
AtomMinor::String => Value::String(decodestr(bs)?.into_owned()).wrap(),
|
|
||||||
AtomMinor::ByteString => Value::ByteString(bs.into_owned()).wrap(),
|
|
||||||
AtomMinor::Symbol => Value::Symbol(decodestr(bs)?.into_owned()).wrap(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decodecompound<'de, I: Iterator<Item = IOResult<IOValue>>>(
|
|
||||||
minor: CompoundMinor,
|
|
||||||
mut iter: I
|
|
||||||
) ->
|
|
||||||
IOResult<IOValue>
|
|
||||||
{
|
|
||||||
match minor {
|
|
||||||
CompoundMinor::Record => {
|
|
||||||
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
|
|
||||||
if vs.len() < 1 {
|
|
||||||
Err(io_syntax_error("Too few elements in encoded record"))
|
|
||||||
} else {
|
|
||||||
Ok(Value::Record(Record(vs)).wrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CompoundMinor::Sequence => {
|
|
||||||
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
|
|
||||||
Ok(Value::Sequence(vs).wrap())
|
|
||||||
}
|
|
||||||
CompoundMinor::Set => {
|
|
||||||
let mut s = Set::new();
|
|
||||||
for res in iter { s.insert(res?); }
|
|
||||||
Ok(Value::Set(s).wrap())
|
|
||||||
}
|
|
||||||
CompoundMinor::Dictionary => {
|
|
||||||
let mut d = Map::new();
|
|
||||||
while let Some(kres) = iter.next() {
|
|
||||||
let k = kres?;
|
|
||||||
match iter.next() {
|
|
||||||
Some(vres) => {
|
|
||||||
let v = vres?;
|
|
||||||
d.insert(k, v);
|
|
||||||
}
|
|
||||||
None => return Err(io_syntax_error("Missing dictionary value")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(Value::Dictionary(d).wrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,30 +2,275 @@ use num;
|
||||||
use num::bigint::BigInt;
|
use num::bigint::BigInt;
|
||||||
use num::cast::ToPrimitive;
|
use num::cast::ToPrimitive;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use super::constants::{Op, AtomMinor, CompoundMinor};
|
use std::mem;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use super::constants::Tag;
|
||||||
use super::super::IOValue;
|
use super::super::IOValue;
|
||||||
|
|
||||||
use super::super::writer::{Writer, Result, varint};
|
use super::super::writer::{Writer, AnnotationWriter, CompoundWriter, Result, varint};
|
||||||
|
|
||||||
pub struct PackedWriter<'w, W: std::io::Write>(pub &'w mut W);
|
pub enum Suspendable<T> {
|
||||||
|
Active(T),
|
||||||
pub fn write_op<W: std::io::Write>(w: &mut PackedWriter<W>, op: Op, arg: u8) -> Result<()> {
|
Suspended,
|
||||||
w.0.write_all(&[(u8::from(op) << 4) | (arg & 15)])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_header<W: std::io::Write>(w: &mut PackedWriter<W>, op: Op, wirelength: usize) -> Result<()> {
|
impl<T> Suspendable<T> {
|
||||||
if wirelength < 15 {
|
pub fn new(t: T) -> Self {
|
||||||
write_op(w, op, wirelength as u8)
|
Suspendable::Active(t)
|
||||||
} else {
|
}
|
||||||
write_op(w, op, 15)?;
|
|
||||||
varint(w.0, wirelength as u64)?;
|
pub fn suspend(&mut self) -> Self {
|
||||||
|
match self {
|
||||||
|
Suspendable::Active(_) => mem::replace(self, Suspendable::Suspended),
|
||||||
|
Suspendable::Suspended =>
|
||||||
|
panic!("Attempt to suspend suspended Suspendable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resume(&mut self, other: Self) {
|
||||||
|
match self {
|
||||||
|
Suspendable::Suspended =>
|
||||||
|
match other {
|
||||||
|
Suspendable::Active(_) => *self = other,
|
||||||
|
Suspendable::Suspended =>
|
||||||
|
panic!("Attempt to resume from suspended Suspendable"),
|
||||||
|
},
|
||||||
|
Suspendable::Active(_) =>
|
||||||
|
panic!("Attempt to resume non-suspended Suspendable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn take(self) -> T {
|
||||||
|
match self {
|
||||||
|
Suspendable::Active(t) => t,
|
||||||
|
Suspendable::Suspended =>
|
||||||
|
panic!("Attempt to take from suspended Suspendable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for Suspendable<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
match self {
|
||||||
|
Suspendable::Suspended => panic!("Suspended Suspendable at deref"),
|
||||||
|
Suspendable::Active(t) => t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for Suspendable<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
match self {
|
||||||
|
Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"),
|
||||||
|
Suspendable::Active(t) => t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PackedWriter<W: std::io::Write>(Suspendable<W>);
|
||||||
|
|
||||||
|
impl PackedWriter<Vec<u8>> {
|
||||||
|
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> {
|
||||||
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
let w = &mut PackedWriter::new(&mut buf);
|
||||||
|
w.write(v)?;
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: std::io::Write> PackedWriter<W> {
|
||||||
|
pub fn new(write: W) -> Self {
|
||||||
|
PackedWriter(Suspendable::new(write))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn w(&mut self) -> &mut W {
|
||||||
|
self.0.deref_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_byte(&mut self, b: u8) -> Result<()> {
|
||||||
|
self.w().write_all(&[b])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_medium_integer(&mut self, bs: &[u8]) -> Result<()> {
|
||||||
|
let count: u8 = bs.len().try_into().unwrap();
|
||||||
|
if count > 16 || count < 1 { panic!("Invalid medium_integer count: {}", count) }
|
||||||
|
self.write_byte(Tag::MediumInteger(count).into())?;
|
||||||
|
self.w().write_all(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> Result<()> {
|
||||||
|
self.write_byte(tag.into())?;
|
||||||
|
varint(&mut self.w(), bs.len().try_into().unwrap())?;
|
||||||
|
self.w().write_all(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn suspend(&mut self) -> Self {
|
||||||
|
PackedWriter(self.0.suspend())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resume(&mut self, other: Self) {
|
||||||
|
self.0.resume(other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BinaryOrderWriter(Vec<Vec<u8>>);
|
||||||
|
|
||||||
|
impl BinaryOrderWriter {
|
||||||
|
fn new() -> Self {
|
||||||
|
BinaryOrderWriter(vec![vec![]])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop(&mut self) -> PackedWriter<Vec<u8>> {
|
||||||
|
PackedWriter::new(self.0.pop().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, w: PackedWriter<Vec<u8>>) {
|
||||||
|
self.0.push(w.0.take())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn items(&self) -> &Vec<Vec<u8>> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn items_mut(&mut self) -> &mut Vec<Vec<u8>> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buffer(&mut self) -> &mut Vec<u8> {
|
||||||
|
self.0.last_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish<W: WriteWriter>(mut self, w: &mut W) -> Result<()> {
|
||||||
|
if self.buffer().len() != 0 { panic!("Missing final delimit()"); }
|
||||||
|
self.items_mut().pop();
|
||||||
|
self.items_mut().sort();
|
||||||
|
for bs in self.items() {
|
||||||
|
w.write_raw_bytes(&bs)?;
|
||||||
|
}
|
||||||
|
w.write_tag(Tag::End)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_atom<W: std::io::Write>(w: &mut PackedWriter<W>, minor: AtomMinor, bs: &[u8]) -> Result<()> {
|
pub trait WriteWriter: Writer {
|
||||||
write_header(w, Op::Atom(minor), bs.len())?;
|
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()>;
|
||||||
w.0.write_all(bs)
|
fn write_tag(&mut self, tag: Tag) -> Result<()> {
|
||||||
|
self.write_raw_bytes(&[tag.into()])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: std::io::Write> WriteWriter for PackedWriter<W> {
|
||||||
|
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> {
|
||||||
|
self.w().write_all(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WriteWriter for BinaryOrderWriter {
|
||||||
|
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> {
|
||||||
|
use std::io::Write;
|
||||||
|
self.buffer().write_all(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: WriteWriter> AnnotationWriter for T {
|
||||||
|
fn start_annotation(&mut self) -> Result<()> {
|
||||||
|
Ok(self.write_tag(Tag::Annotation)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_value(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: std::io::Write> CompoundWriter for PackedWriter<W> {
|
||||||
|
fn extend(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delimit(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompoundWriter for BinaryOrderWriter {
|
||||||
|
fn extend(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delimit(&mut self) -> Result<()> {
|
||||||
|
self.items_mut().push(vec![]);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! binary_order_writer_method {
|
||||||
|
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) =>
|
||||||
|
(fn $n (&mut self, $($argname : $argty),*) -> $retty {
|
||||||
|
(&mut PackedWriter::new(self.buffer())).$n($($argname),*)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writer for BinaryOrderWriter {
|
||||||
|
type AnnWriter = PackedWriter<Vec<u8>>;
|
||||||
|
type SeqWriter = PackedWriter<Vec<u8>>;
|
||||||
|
type SetWriter = BinaryOrderWriter;
|
||||||
|
|
||||||
|
binary_order_writer_method!(mut align(natural_chunksize: u64) -> Result<()>);
|
||||||
|
|
||||||
|
fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
|
||||||
|
Ok(self.pop())
|
||||||
|
}
|
||||||
|
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
|
||||||
|
self.push(ann);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_order_writer_method!(mut write_bool(v: bool) -> Result<()>);
|
||||||
|
|
||||||
|
binary_order_writer_method!(mut write_f32(v: f32) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_f64(v: f64) -> Result<()>);
|
||||||
|
|
||||||
|
binary_order_writer_method!(mut write_i8(v: i8) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_u8(v: u8) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_i16(v: i16) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_u16(v: u16) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_i32(v: i32) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_u32(v: u32) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_i64(v: i64) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_u64(v: u64) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_i128(v: i128) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_u128(v: u128) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_int(v: &BigInt) -> Result<()>);
|
||||||
|
|
||||||
|
binary_order_writer_method!(mut write_string(v: &str) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> Result<()>);
|
||||||
|
binary_order_writer_method!(mut write_symbol(v: &str) -> Result<()>);
|
||||||
|
|
||||||
|
fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
|
||||||
|
self.write_tag(Tag::Record)?;
|
||||||
|
Ok(self.pop())
|
||||||
|
}
|
||||||
|
fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
|
||||||
|
self.write_tag(Tag::Sequence)?;
|
||||||
|
Ok(self.pop())
|
||||||
|
}
|
||||||
|
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
|
||||||
|
self.push(seq);
|
||||||
|
self.write_tag(Tag::End)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
|
||||||
|
self.write_tag(Tag::Set)?;
|
||||||
|
Ok(BinaryOrderWriter::new())
|
||||||
|
}
|
||||||
|
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
|
||||||
|
self.write_tag(Tag::Dictionary)?;
|
||||||
|
Ok(BinaryOrderWriter::new())
|
||||||
|
}
|
||||||
|
fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
|
||||||
|
set.finish(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! fits_in_bytes {
|
macro_rules! fits_in_bytes {
|
||||||
|
@ -35,38 +280,18 @@ macro_rules! fits_in_bytes {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, W: std::io::Write> PackedWriter<'w, W> {
|
impl<W: std::io::Write> Writer for PackedWriter<W>
|
||||||
pub fn write_noop(&mut self) -> Result<()> {
|
{
|
||||||
write_op(self, Op::Reserved(3), 15)
|
type AnnWriter = Self;
|
||||||
}
|
type SeqWriter = Self;
|
||||||
}
|
type SetWriter = BinaryOrderWriter;
|
||||||
|
|
||||||
impl<'w> PackedWriter<'w, &'w mut Vec<u8>> {
|
fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
|
||||||
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> {
|
Ok(self.suspend())
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
|
||||||
PackedWriter(&mut buf).write(v)?;
|
|
||||||
Ok(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
|
|
||||||
type Pointer = ();
|
|
||||||
type Annotation = ();
|
|
||||||
type Compound = bool;
|
|
||||||
type Dictionary = bool;
|
|
||||||
type StreamedAtom = ();
|
|
||||||
type KeyPointer = ();
|
|
||||||
|
|
||||||
fn start_annotation(&mut self) -> Result<Self::Annotation> {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_annotation(&mut self, _a: &mut Self::Annotation, annotation: &IOValue) -> Result<()> {
|
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
|
||||||
write_header(self, Op::Misc(0), 5)?;
|
self.resume(ann);
|
||||||
self.write(annotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_annotation(&mut self, _a: Self::Annotation, _value_p: Self::Pointer) -> Result<Self::Pointer> {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,235 +300,182 @@ impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_bool(&mut self, v: bool) -> Result<()> {
|
fn write_bool(&mut self, v: bool) -> Result<()> {
|
||||||
write_op(self, Op::Misc(0), if v { 1 } else { 0 })
|
self.write_tag(if v { Tag::True } else { Tag::False })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_f32(&mut self, v: f32) -> Result<()> {
|
fn write_f32(&mut self, v: f32) -> Result<()> {
|
||||||
write_op(self, Op::Misc(0), 2)?;
|
self.write_tag(Tag::Float)?;
|
||||||
self.0.write_all(&u32::to_be_bytes(f32::to_bits(v)))
|
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_f64(&mut self, v: f64) -> Result<()> {
|
fn write_f64(&mut self, v: f64) -> Result<()> {
|
||||||
write_op(self, Op::Misc(0), 3)?;
|
self.write_tag(Tag::Double)?;
|
||||||
self.0.write_all(&u64::to_be_bytes(f64::to_bits(v)))
|
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i8(&mut self, v: i8) -> Result<()> {
|
fn write_i8(&mut self, v: i8) -> Result<()> {
|
||||||
if v >= 0 && v <= 12 { return write_op(self, Op::Misc(3), v as u8) }
|
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
|
||||||
if v >= -3 && v < 0 { return write_op(self, Op::Misc(3), (v + 16) as u8) }
|
self.write_medium_integer(&[v as u8])
|
||||||
write_atom(self, AtomMinor::SignedInteger, &[v as u8])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u8(&mut self, v: u8) -> Result<()> {
|
fn write_u8(&mut self, v: u8) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i8(w) }
|
if let Ok(w) = v.try_into() { return self.write_i8(w) }
|
||||||
write_atom(self, AtomMinor::SignedInteger, &[0, v])
|
self.write_medium_integer(&[0, v])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i16(&mut self, v: i16) -> Result<()> {
|
fn write_i16(&mut self, v: i16) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i8(w) }
|
if let Ok(w) = v.try_into() { return self.write_i8(w) }
|
||||||
write_atom(self, AtomMinor::SignedInteger, &[(v >> 8) as u8, (v & 255) as u8])
|
self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u16(&mut self, v: u16) -> Result<()> {
|
fn write_u16(&mut self, v: u16) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
||||||
write_atom(self, AtomMinor::SignedInteger, &[0, (v >> 8) as u8, (v & 255) as u8])
|
self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i32(&mut self, v: i32) -> Result<()> {
|
fn write_i32(&mut self, v: i32) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
||||||
if fits_in_bytes!(v, 3) {
|
if fits_in_bytes!(v, 3) {
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 16) as u8,
|
return self.write_medium_integer(&[(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8]);
|
||||||
}
|
}
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 24) as u8,
|
self.write_medium_integer(&[(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u32(&mut self, v: u32) -> Result<()> {
|
fn write_u32(&mut self, v: u32) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[0,
|
self.write_medium_integer(&[0,
|
||||||
(v >> 24) as u8,
|
(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i64(&mut self, v: i64) -> Result<()> {
|
fn write_i64(&mut self, v: i64) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||||
if fits_in_bytes!(v, 5) {
|
if fits_in_bytes!(v, 5) {
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 32) as u8,
|
return self.write_medium_integer(&[(v >> 32) as u8,
|
||||||
(v >> 24) as u8,
|
(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8]);
|
||||||
}
|
}
|
||||||
if fits_in_bytes!(v, 6) {
|
if fits_in_bytes!(v, 6) {
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 40) as u8,
|
return self.write_medium_integer(&[(v >> 40) as u8,
|
||||||
(v >> 32) as u8,
|
(v >> 32) as u8,
|
||||||
(v >> 24) as u8,
|
(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8]);
|
||||||
}
|
}
|
||||||
if fits_in_bytes!(v, 7) {
|
if fits_in_bytes!(v, 7) {
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 48) as u8,
|
return self.write_medium_integer(&[(v >> 48) as u8,
|
||||||
(v >> 40) as u8,
|
(v >> 40) as u8,
|
||||||
(v >> 32) as u8,
|
(v >> 32) as u8,
|
||||||
(v >> 24) as u8,
|
(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8]);
|
||||||
}
|
}
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 56) as u8,
|
self.write_medium_integer(&[(v >> 56) as u8,
|
||||||
(v >> 48) as u8,
|
(v >> 48) as u8,
|
||||||
(v >> 40) as u8,
|
(v >> 40) as u8,
|
||||||
(v >> 32) as u8,
|
(v >> 32) as u8,
|
||||||
(v >> 24) as u8,
|
(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u64(&mut self, v: u64) -> Result<()> {
|
fn write_u64(&mut self, v: u64) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &[0,
|
self.write_medium_integer(&[0,
|
||||||
(v >> 56) as u8,
|
(v >> 56) as u8,
|
||||||
(v >> 48) as u8,
|
(v >> 48) as u8,
|
||||||
(v >> 40) as u8,
|
(v >> 40) as u8,
|
||||||
(v >> 32) as u8,
|
(v >> 32) as u8,
|
||||||
(v >> 24) as u8,
|
(v >> 24) as u8,
|
||||||
(v >> 16) as u8,
|
(v >> 16) as u8,
|
||||||
(v >> 8) as u8,
|
(v >> 8) as u8,
|
||||||
(v & 255) as u8]);
|
(v & 255) as u8])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i128(&mut self, v: i128) -> Result<()> {
|
fn write_i128(&mut self, v: i128) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||||
let bs: [u8; 16] = v.to_be_bytes();
|
let bs: [u8; 16] = v.to_be_bytes();
|
||||||
if fits_in_bytes!(v, 9) { return write_atom(self, AtomMinor::SignedInteger, &bs[7..]); }
|
if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); }
|
||||||
if fits_in_bytes!(v, 10) { return write_atom(self, AtomMinor::SignedInteger, &bs[6..]); }
|
if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); }
|
||||||
if fits_in_bytes!(v, 11) { return write_atom(self, AtomMinor::SignedInteger, &bs[5..]); }
|
if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); }
|
||||||
if fits_in_bytes!(v, 12) { return write_atom(self, AtomMinor::SignedInteger, &bs[4..]); }
|
if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); }
|
||||||
if fits_in_bytes!(v, 13) { return write_atom(self, AtomMinor::SignedInteger, &bs[3..]); }
|
if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); }
|
||||||
if fits_in_bytes!(v, 14) { return write_atom(self, AtomMinor::SignedInteger, &bs[2..]); }
|
if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); }
|
||||||
if fits_in_bytes!(v, 15) { return write_atom(self, AtomMinor::SignedInteger, &bs[1..]); }
|
if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); }
|
||||||
return write_atom(self, AtomMinor::SignedInteger, &bs);
|
self.write_medium_integer(&bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u128(&mut self, v: u128) -> Result<()> {
|
fn write_u128(&mut self, v: u128) -> Result<()> {
|
||||||
if let Ok(w) = v.try_into() { return self.write_i128(w) }
|
if let Ok(w) = v.try_into() { return self.write_i128(w) }
|
||||||
let bs: [u8; 16] = v.to_be_bytes();
|
let bs: [u8; 16] = v.to_be_bytes();
|
||||||
write_header(self, Op::Atom(AtomMinor::SignedInteger), bs.len() + 1)?;
|
self.write_tag(Tag::SignedInteger)?;
|
||||||
self.0.write_all(&[0])?;
|
varint(&mut self.w(), 17)?;
|
||||||
self.0.write_all(&bs)
|
self.write_byte(0)?;
|
||||||
|
self.write_raw_bytes(&bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_int(&mut self, v: &BigInt) -> Result<()> {
|
fn write_int(&mut self, v: &BigInt) -> Result<()> {
|
||||||
match v.to_i8() {
|
match v.to_i8() {
|
||||||
Some(n) => self.write_i8(n),
|
Some(n) => self.write_i8(n),
|
||||||
None => write_atom(self, AtomMinor::SignedInteger, &v.to_signed_bytes_be()),
|
None => {
|
||||||
|
match v.to_i128() {
|
||||||
|
Some(n) => self.write_i128(n),
|
||||||
|
None => self.write_atom(Tag::SignedInteger, &v.to_signed_bytes_be()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string(&mut self, v: &str) -> Result<()> {
|
fn write_string(&mut self, v: &str) -> Result<()> {
|
||||||
write_atom(self, AtomMinor::String, v.as_bytes())
|
self.write_atom(Tag::String, v.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_bytes(&mut self, v: &[u8]) -> Result<()> {
|
fn write_bytes(&mut self, v: &[u8]) -> Result<()> {
|
||||||
write_atom(self, AtomMinor::ByteString, v)
|
self.write_atom(Tag::ByteString, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_symbol(&mut self, v: &str) -> Result<()> {
|
fn write_symbol(&mut self, v: &str) -> Result<()> {
|
||||||
write_atom(self, AtomMinor::Symbol, v.as_bytes())
|
self.write_atom(Tag::Symbol, v.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream_string(&mut self) -> Result<Option<Self::StreamedAtom>> {
|
fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
|
||||||
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::String).into())?;
|
self.write_tag(Tag::Record)?;
|
||||||
Ok(Some(()))
|
Ok(self.suspend())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream_bytes(&mut self) -> Result<Option<Self::StreamedAtom>> {
|
fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
|
||||||
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::ByteString).into())?;
|
self.write_tag(Tag::Sequence)?;
|
||||||
Ok(Some(()))
|
Ok(self.suspend())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream_symbol(&mut self) -> Result<Option<Self::StreamedAtom>> {
|
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
|
||||||
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::Symbol).into())?;
|
self.resume(seq);
|
||||||
Ok(Some(()))
|
self.write_tag(Tag::End)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_atom(&mut self, _s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()> {
|
fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
|
||||||
self.write_bytes(bs)
|
self.write_tag(Tag::Set)?;
|
||||||
|
Ok(BinaryOrderWriter::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_atom(&mut self, _s: Self::StreamedAtom) -> Result<()> {
|
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
|
||||||
write_op(self, Op::Misc(0), 4)
|
self.write_tag(Tag::Dictionary)?;
|
||||||
|
Ok(BinaryOrderWriter::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_record(&mut self, field_count: usize) -> Result<Self::Compound> {
|
fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
|
||||||
write_header(self, Op::Compound(CompoundMinor::Record), field_count + 1)?;
|
set.finish(self)
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_sequence(&mut self, item_count: usize) -> Result<Self::Compound> {
|
|
||||||
write_header(self, Op::Compound(CompoundMinor::Sequence), item_count)?;
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_set(&mut self, item_count: usize) -> Result<Self::Compound> {
|
|
||||||
write_header(self, Op::Compound(CompoundMinor::Set), item_count)?;
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stream_record(&mut self) -> Result<Option<Self::Compound>> {
|
|
||||||
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Record).into())?;
|
|
||||||
Ok(Some(true))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stream_sequence(&mut self) -> Result<Option<Self::Compound>> {
|
|
||||||
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Sequence).into())?;
|
|
||||||
Ok(Some(true))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stream_set(&mut self) -> Result<Option<Self::Compound>> {
|
|
||||||
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Set).into())?;
|
|
||||||
Ok(Some(true))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extend_compound(&mut self, _s: &mut Self::Compound, _value_p: Self::Pointer) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_compound(&mut self, s: Self::Compound) -> Result<()> {
|
|
||||||
if s {
|
|
||||||
write_op(self, Op::Misc(0), 4)
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_dictionary(&mut self, entry_count: usize) -> Result<Self::Dictionary> {
|
|
||||||
write_header(self, Op::Compound(CompoundMinor::Dictionary), entry_count << 1)?;
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stream_dictionary(&mut self) -> Result<Option<Self::Dictionary>> {
|
|
||||||
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Dictionary).into())?;
|
|
||||||
Ok(Some(true))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extend_dictionary_key(&mut self, _s: &mut Self::Dictionary, _key_p: Self::Pointer) -> Result<Self::KeyPointer> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extend_dictionary_value(&mut self, _s: &mut Self::Dictionary, _key_p: Self::KeyPointer, _value_p: Self::Pointer) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_dictionary(&mut self, s: Self::Dictionary) -> Result<()> {
|
|
||||||
self.end_compound(s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,13 @@ pub type IOResult<T> = std::result::Result<T, Error>;
|
||||||
pub type ReaderResult<T> = std::result::Result<T, error::Error>;
|
pub type ReaderResult<T> = std::result::Result<T, error::Error>;
|
||||||
|
|
||||||
pub trait Reader<'de> {
|
pub trait Reader<'de> {
|
||||||
type CompoundInfo: Copy;
|
|
||||||
|
|
||||||
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>;
|
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>;
|
||||||
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
|
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()>;
|
||||||
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
|
fn open_sequence_or_set(&mut self) -> ReaderResult<()>;
|
||||||
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
|
fn open_sequence(&mut self) -> ReaderResult<()>;
|
||||||
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
|
fn open_set(&mut self) -> ReaderResult<()>;
|
||||||
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
|
fn open_dictionary(&mut self) -> ReaderResult<()>;
|
||||||
fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()>;
|
fn close_compound(&mut self) -> ReaderResult<bool>;
|
||||||
fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult<bool>;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -28,10 +25,7 @@ pub trait Reader<'de> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> {
|
fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> {
|
||||||
match self.next(read_annotations)? {
|
self.next(read_annotations)?.ok_or_else(|| io_eof())
|
||||||
None => Err(io_eof()),
|
|
||||||
Some(v) => Ok(v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_boolean(&mut self) -> ReaderResult<bool> { self.demand_next(false)?.value().to_boolean() }
|
fn next_boolean(&mut self) -> ReaderResult<bool> { self.demand_next(false)?.value().to_boolean() }
|
||||||
|
@ -61,30 +55,24 @@ pub trait Reader<'de> {
|
||||||
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned()))
|
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_option(&mut self) ->
|
fn open_option(&mut self) -> ReaderResult<bool>
|
||||||
ReaderResult<(bool, CompoundBody<Self::CompoundInfo>)>
|
|
||||||
where
|
|
||||||
Self: Sized
|
|
||||||
{
|
{
|
||||||
let mut compound_body = self.open_record(None)?;
|
self.open_record(None)?;
|
||||||
let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?;
|
let label: &str = &self.next_symbol()?;
|
||||||
match label {
|
match label {
|
||||||
"None" => Ok((false, compound_body)),
|
"None" => Ok(false),
|
||||||
"Some" => Ok((true, compound_body)),
|
"Some" => Ok(true),
|
||||||
_ => Err(error::Error::Expected(ExpectedKind::Option,
|
_ => Err(error::Error::Expected(ExpectedKind::Option,
|
||||||
Received::ReceivedRecordWithLabel(label.to_owned()))),
|
Received::ReceivedRecordWithLabel(label.to_owned()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) ->
|
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<()>
|
||||||
ReaderResult<CompoundBody<Self::CompoundInfo>>
|
|
||||||
where
|
|
||||||
Self: Sized
|
|
||||||
{
|
{
|
||||||
let mut compound_body = self.open_record(arity)?;
|
self.open_record(arity)?;
|
||||||
let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?;
|
let label: &str = &self.next_symbol()?;
|
||||||
if label == name {
|
if label == name {
|
||||||
Ok(compound_body)
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
|
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
|
||||||
Received::ReceivedRecordWithLabel(label.to_owned())))
|
Received::ReceivedRecordWithLabel(label.to_owned())))
|
||||||
|
@ -101,129 +89,24 @@ pub trait Reader<'de> {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
|
fn skip_remainder(&mut self) -> ReaderResult<()> {
|
||||||
type CompoundInfo = R::CompoundInfo;
|
while !self.close_compound()? {
|
||||||
|
self.skip_value()?;
|
||||||
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
|
|
||||||
(*self).next(read_annotations)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
|
||||||
(*self).open_record(arity)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
|
||||||
(*self).open_sequence_or_set()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
|
||||||
(*self).open_sequence()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
|
||||||
(*self).open_set()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
|
|
||||||
(*self).open_dictionary()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()> {
|
|
||||||
(*self).close_compound_counted(info)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult<bool> {
|
|
||||||
(*self).close_compound_stream(info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct CompoundBody<I: Copy> {
|
|
||||||
pub info: I,
|
|
||||||
pub limit: CompoundLimit,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum CompoundLimit {
|
|
||||||
Counted(usize),
|
|
||||||
Streaming,
|
|
||||||
Finished,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: Copy> CompoundBody<I> {
|
|
||||||
pub fn counted(info: I, size: usize) -> Self {
|
|
||||||
CompoundBody { info, limit: CompoundLimit::Counted(size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn streaming(info: I) -> Self {
|
|
||||||
CompoundBody { info, limit: CompoundLimit::Streaming }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<bool> {
|
|
||||||
match self.limit {
|
|
||||||
CompoundLimit::Counted(ref mut n) =>
|
|
||||||
if *n == 0 {
|
|
||||||
read.close_compound_counted(self.info)?;
|
|
||||||
self.limit = CompoundLimit::Finished;
|
|
||||||
Ok(false)
|
|
||||||
} else {
|
|
||||||
*n = *n - 1;
|
|
||||||
Ok(true)
|
|
||||||
},
|
|
||||||
CompoundLimit::Streaming =>
|
|
||||||
Ok(!read.close_compound_stream(self.info)?),
|
|
||||||
CompoundLimit::Finished =>
|
|
||||||
Ok(false),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_symbol<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<Option<Cow<'de, str>>> {
|
|
||||||
match self.more_expected(read)? {
|
|
||||||
false => Ok(None),
|
|
||||||
true => Ok(Some(read.next_symbol()?)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_value<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) ->
|
|
||||||
ReaderResult<Option<IOValue>>
|
|
||||||
{
|
|
||||||
match self.more_expected(read)? {
|
|
||||||
false => Ok(None),
|
|
||||||
true => Ok(Some(read.demand_next(read_annotations)?)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) ->
|
|
||||||
ReaderResult<Vec<IOValue>>
|
|
||||||
{
|
|
||||||
let mut result = Vec::new();
|
|
||||||
while let Some(v) = self.next_value(read, read_annotations)? {
|
|
||||||
result.push(v);
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn skip_remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) ->
|
|
||||||
ReaderResult<()>
|
|
||||||
{
|
|
||||||
while let true = self.more_expected(read)? {
|
|
||||||
read.skip_value()?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> {
|
fn ensure_more_expected(&mut self) -> ReaderResult<()> {
|
||||||
if self.more_expected(read)? {
|
if !self.close_compound()? {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(error::Error::MissingItem)
|
Err(error::Error::MissingItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_complete<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> {
|
fn ensure_complete(&mut self) -> ReaderResult<()> {
|
||||||
if self.more_expected(read)? {
|
if !self.close_compound()? {
|
||||||
Err(error::Error::MissingCloseDelimiter)
|
Err(error::Error::MissingCloseDelimiter)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -231,6 +114,37 @@ impl<I: Copy> CompoundBody<I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
|
||||||
|
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
|
||||||
|
(*self).next(read_annotations)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()> {
|
||||||
|
(*self).open_record(arity)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_sequence_or_set(&mut self) -> ReaderResult<()> {
|
||||||
|
(*self).open_sequence_or_set()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_sequence(&mut self) -> ReaderResult<()> {
|
||||||
|
(*self).open_sequence()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_set(&mut self) -> ReaderResult<()> {
|
||||||
|
(*self).open_set()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_dictionary(&mut self) -> ReaderResult<()> {
|
||||||
|
(*self).open_dictionary()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_compound(&mut self) -> ReaderResult<bool> {
|
||||||
|
(*self).close_compound()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait BinarySource<'de> {
|
pub trait BinarySource<'de> {
|
||||||
fn skip(&mut self) -> IOResult<()>;
|
fn skip(&mut self) -> IOResult<()>;
|
||||||
fn peek(&mut self) -> IOResult<u8>;
|
fn peek(&mut self) -> IOResult<u8>;
|
||||||
|
|
|
@ -236,16 +236,16 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
|
||||||
// doesn't escape strings/symbols properly.
|
// doesn't escape strings/symbols properly.
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Value::Boolean(false) => f.write_str("#false"),
|
Value::Boolean(false) => f.write_str("#f"),
|
||||||
Value::Boolean(true) => f.write_str("#true"),
|
Value::Boolean(true) => f.write_str("#t"),
|
||||||
Value::Float(Float(v)) => write!(f, "{:?}f", v),
|
Value::Float(Float(v)) => write!(f, "{:?}f", v),
|
||||||
Value::Double(Double(v)) => write!(f, "{:?}", v),
|
Value::Double(Double(v)) => write!(f, "{:?}", v),
|
||||||
Value::SignedInteger(v) => write!(f, "{}", v),
|
Value::SignedInteger(v) => write!(f, "{}", v),
|
||||||
Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping!
|
Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping!
|
||||||
Value::ByteString(ref v) => {
|
Value::ByteString(ref v) => {
|
||||||
f.write_str("#hex{")?;
|
f.write_str("#x\"")?;
|
||||||
for b in v { write!(f, "{:02x}", b)? }
|
for b in v { write!(f, "{:02x}", b)? }
|
||||||
f.write_str("}")
|
f.write_str("\"")
|
||||||
}
|
}
|
||||||
Value::Symbol(ref v) => {
|
Value::Symbol(ref v) => {
|
||||||
// TODO: proper escaping!
|
// TODO: proper escaping!
|
||||||
|
@ -266,7 +266,7 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
|
||||||
}
|
}
|
||||||
Value::Sequence(ref v) => v.fmt(f),
|
Value::Sequence(ref v) => v.fmt(f),
|
||||||
Value::Set(ref v) => {
|
Value::Set(ref v) => {
|
||||||
f.write_str("#set")?;
|
f.write_str("#")?;
|
||||||
f.debug_set().entries(v.iter()).finish()
|
f.debug_set().entries(v.iter()).finish()
|
||||||
}
|
}
|
||||||
Value::Dictionary(ref v) => f.debug_map().entries(v.iter()).finish(),
|
Value::Dictionary(ref v) => f.debug_map().entries(v.iter()).finish(),
|
||||||
|
@ -849,7 +849,7 @@ impl<N: NestedValue<D>, D: Domain> Annotations<N, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An possibly-annotated Value, with annotations (themselves
|
/// A possibly-annotated Value, with annotations (themselves
|
||||||
/// possibly-annotated) in order of appearance.
|
/// possibly-annotated) in order of appearance.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Annotations<N, D>, pub Value<N, D>);
|
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Annotations<N, D>, pub Value<N, D>);
|
||||||
|
|
|
@ -6,79 +6,77 @@ use super::value::{Domain, Value, NestedValue, IOValue, UnwrappedIOValue, Float,
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
pub trait Writer {
|
pub trait AnnotationWriter: Writer {
|
||||||
type Pointer;
|
fn start_annotation(&mut self) -> Result<()>;
|
||||||
type Annotation;
|
fn start_value(&mut self) -> Result<()>;
|
||||||
type Compound;
|
}
|
||||||
type Dictionary;
|
|
||||||
type StreamedAtom;
|
pub trait CompoundWriter: Writer {
|
||||||
type KeyPointer;
|
fn extend(&mut self) -> Result<()>;
|
||||||
|
fn delimit(&mut self) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Writer: Sized {
|
||||||
|
type AnnWriter: AnnotationWriter;
|
||||||
|
type SeqWriter: CompoundWriter;
|
||||||
|
type SetWriter: CompoundWriter;
|
||||||
|
|
||||||
fn align(&mut self, natural_chunksize: u64) -> Result<()>;
|
fn align(&mut self, natural_chunksize: u64) -> Result<()>;
|
||||||
|
|
||||||
fn start_annotation(&mut self) -> Result<Self::Annotation>;
|
fn start_annotations(&mut self) -> Result<Self::AnnWriter>;
|
||||||
fn extend_annotation(&mut self, a: &mut Self::Annotation, annotation: &IOValue) -> Result<()>;
|
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()>;
|
||||||
fn end_annotation(&mut self, a: Self::Annotation, value_p: Self::Pointer) -> Result<Self::Pointer>;
|
|
||||||
|
|
||||||
fn write_bool(&mut self, v: bool) -> Result<Self::Pointer>;
|
fn write_bool(&mut self, v: bool) -> Result<()>;
|
||||||
|
|
||||||
fn write_f32(&mut self, v: f32) -> Result<Self::Pointer>;
|
fn write_f32(&mut self, v: f32) -> Result<()>;
|
||||||
fn write_f64(&mut self, v: f64) -> Result<Self::Pointer>;
|
fn write_f64(&mut self, v: f64) -> Result<()>;
|
||||||
|
|
||||||
fn write_i8(&mut self, v: i8) -> Result<Self::Pointer>;
|
fn write_i8(&mut self, v: i8) -> Result<()>;
|
||||||
fn write_u8(&mut self, v: u8) -> Result<Self::Pointer>;
|
fn write_u8(&mut self, v: u8) -> Result<()>;
|
||||||
fn write_i16(&mut self, v: i16) -> Result<Self::Pointer>;
|
fn write_i16(&mut self, v: i16) -> Result<()>;
|
||||||
fn write_u16(&mut self, v: u16) -> Result<Self::Pointer>;
|
fn write_u16(&mut self, v: u16) -> Result<()>;
|
||||||
fn write_i32(&mut self, v: i32) -> Result<Self::Pointer>;
|
fn write_i32(&mut self, v: i32) -> Result<()>;
|
||||||
fn write_u32(&mut self, v: u32) -> Result<Self::Pointer>;
|
fn write_u32(&mut self, v: u32) -> Result<()>;
|
||||||
fn write_i64(&mut self, v: i64) -> Result<Self::Pointer>;
|
fn write_i64(&mut self, v: i64) -> Result<()>;
|
||||||
fn write_u64(&mut self, v: u64) -> Result<Self::Pointer>;
|
fn write_u64(&mut self, v: u64) -> Result<()>;
|
||||||
fn write_i128(&mut self, v: i128) -> Result<Self::Pointer>;
|
fn write_i128(&mut self, v: i128) -> Result<()>;
|
||||||
fn write_u128(&mut self, v: u128) -> Result<Self::Pointer>;
|
fn write_u128(&mut self, v: u128) -> Result<()>;
|
||||||
fn write_int(&mut self, v: &BigInt) -> Result<Self::Pointer>;
|
fn write_int(&mut self, v: &BigInt) -> Result<()>;
|
||||||
|
|
||||||
fn write_string(&mut self, v: &str) -> Result<Self::Pointer>;
|
fn write_string(&mut self, v: &str) -> Result<()>;
|
||||||
fn write_bytes(&mut self, v: &[u8]) -> Result<Self::Pointer>;
|
fn write_bytes(&mut self, v: &[u8]) -> Result<()>;
|
||||||
fn write_symbol(&mut self, v: &str) -> Result<Self::Pointer>;
|
fn write_symbol(&mut self, v: &str) -> Result<()>;
|
||||||
|
|
||||||
fn stream_string(&mut self) -> Result<Option<Self::StreamedAtom>>;
|
fn start_record(&mut self, field_count: Option<usize>) -> Result<Self::SeqWriter>;
|
||||||
fn stream_bytes(&mut self) -> Result<Option<Self::StreamedAtom>>;
|
fn start_sequence(&mut self, item_count: Option<usize>) -> Result<Self::SeqWriter>;
|
||||||
fn stream_symbol(&mut self) -> Result<Option<Self::StreamedAtom>>;
|
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()>;
|
||||||
fn extend_atom(&mut self, s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()>;
|
|
||||||
fn end_atom(&mut self, s: Self::StreamedAtom) -> Result<Self::Pointer>;
|
|
||||||
|
|
||||||
fn start_record(&mut self, field_count: usize) -> Result<Self::Compound>;
|
fn start_set(&mut self, item_count: Option<usize>) -> Result<Self::SetWriter>;
|
||||||
fn start_sequence(&mut self, item_count: usize) -> Result<Self::Compound>;
|
fn start_dictionary(&mut self, entry_count: Option<usize>) -> Result<Self::SetWriter>;
|
||||||
fn start_set(&mut self, item_count: usize) -> Result<Self::Compound>;
|
fn end_set(&mut self, set: Self::SetWriter) -> Result<()>;
|
||||||
fn stream_record(&mut self) -> Result<Option<Self::Compound>>;
|
|
||||||
fn stream_sequence(&mut self) -> Result<Option<Self::Compound>>;
|
|
||||||
fn stream_set(&mut self) -> Result<Option<Self::Compound>>;
|
|
||||||
fn extend_compound(&mut self, s: &mut Self::Compound, value_p: Self::Pointer) -> Result<()>;
|
|
||||||
fn end_compound(&mut self, s: Self::Compound) -> Result<Self::Pointer>;
|
|
||||||
|
|
||||||
fn start_dictionary(&mut self, entry_count: usize) -> Result<Self::Dictionary>;
|
|
||||||
fn stream_dictionary(&mut self) -> Result<Option<Self::Dictionary>>;
|
|
||||||
fn extend_dictionary_key(&mut self, s: &mut Self::Dictionary, key_p: Self::Pointer) -> Result<Self::KeyPointer>;
|
|
||||||
fn extend_dictionary_value(&mut self, s: &mut Self::Dictionary, key_p: Self::KeyPointer, value_p: Self::Pointer) -> Result<()>;
|
|
||||||
fn end_dictionary(&mut self, s: Self::Dictionary) -> Result<Self::Pointer>;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
fn write(&mut self, v: &IOValue) -> Result<Self::Pointer> {
|
fn write(&mut self, v: &IOValue) -> Result<()> {
|
||||||
match v.annotations().maybe_slice() {
|
match v.annotations().maybe_slice() {
|
||||||
None => self.write_value(v.value()),
|
None => {
|
||||||
|
self.write_value(v.value())?;
|
||||||
|
}
|
||||||
Some(anns) => {
|
Some(anns) => {
|
||||||
let mut a = self.start_annotation()?;
|
let mut a = self.start_annotations()?;
|
||||||
for ann in anns {
|
for ann in anns {
|
||||||
self.extend_annotation(&mut a, ann)?;
|
a.start_annotation()?;
|
||||||
|
a.write(ann)?;
|
||||||
}
|
}
|
||||||
let p = self.write_value(v.value())?;
|
a.start_value()?;
|
||||||
self.end_annotation(a, p)
|
a.write_value(v.value())?;
|
||||||
|
self.end_annotations(a)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<Self::Pointer> {
|
fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<()> {
|
||||||
match v {
|
match v {
|
||||||
Value::Boolean(b) => self.write_bool(*b),
|
Value::Boolean(b) => self.write_bool(*b),
|
||||||
Value::Float(Float(f)) => self.write_f32(*f),
|
Value::Float(Float(f)) => self.write_f32(*f),
|
||||||
|
@ -92,60 +90,50 @@ pub trait Writer {
|
||||||
Value::ByteString(ref bs) => self.write_bytes(bs),
|
Value::ByteString(ref bs) => self.write_bytes(bs),
|
||||||
Value::Symbol(ref s) => self.write_symbol(s),
|
Value::Symbol(ref s) => self.write_symbol(s),
|
||||||
Value::Record(r) => {
|
Value::Record(r) => {
|
||||||
let mut c = self.start_record(r.arity())?;
|
let mut c = self.start_record(Some(r.arity()))?;
|
||||||
let p = self.write(r.label())?;
|
c.extend()?;
|
||||||
self.extend_compound(&mut c, p)?;
|
c.write(r.label())?;
|
||||||
|
c.delimit()?;
|
||||||
for f in r.fields() {
|
for f in r.fields() {
|
||||||
let p = self.write(f)?;
|
c.extend()?;
|
||||||
self.extend_compound(&mut c, p)?;
|
c.write(f)?;
|
||||||
|
c.delimit()?;
|
||||||
}
|
}
|
||||||
self.end_compound(c)
|
self.end_seq(c)
|
||||||
}
|
}
|
||||||
Value::Sequence(ref vs) => {
|
Value::Sequence(ref vs) => {
|
||||||
let mut c = self.start_sequence(vs.len())?;
|
let mut c = self.start_sequence(Some(vs.len()))?;
|
||||||
for v in vs {
|
for v in vs {
|
||||||
let p = self.write(v)?;
|
c.extend()?;
|
||||||
self.extend_compound(&mut c, p)?;
|
c.write(v)?;
|
||||||
|
c.delimit()?;
|
||||||
}
|
}
|
||||||
self.end_compound(c)
|
self.end_seq(c)
|
||||||
}
|
}
|
||||||
Value::Set(ref vs) => {
|
Value::Set(ref vs) => {
|
||||||
let mut c = self.start_set(vs.len())?;
|
let mut c = self.start_set(Some(vs.len()))?;
|
||||||
for v in vs {
|
for v in vs {
|
||||||
let p = self.write(v)?;
|
c.extend()?;
|
||||||
self.extend_compound(&mut c, p)?;
|
c.write(v)?;
|
||||||
|
c.delimit()?;
|
||||||
}
|
}
|
||||||
self.end_compound(c)
|
self.end_set(c)
|
||||||
}
|
}
|
||||||
Value::Dictionary(ref vs) => {
|
Value::Dictionary(ref vs) => {
|
||||||
let mut d = self.start_dictionary(vs.len())?;
|
let mut c = self.start_dictionary(Some(vs.len()))?;
|
||||||
for (k, v) in vs {
|
for (k, v) in vs {
|
||||||
let p = self.write(k)?;
|
c.extend()?;
|
||||||
let kp = self.extend_dictionary_key(&mut d, p)?;
|
c.write(k)?;
|
||||||
let p = self.write(v)?;
|
c.write(v)?;
|
||||||
self.extend_dictionary_value(&mut d, kp, p)?;
|
c.delimit()?;
|
||||||
}
|
}
|
||||||
self.end_dictionary(d)
|
self.end_set(c)
|
||||||
}
|
}
|
||||||
Value::Domain(ref d) => self.write(&d.as_preserves()?)
|
Value::Domain(ref d) => self.write(&d.as_preserves()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bigvarint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<usize> {
|
|
||||||
let mut byte_count = 0;
|
|
||||||
loop {
|
|
||||||
byte_count = byte_count + 4;
|
|
||||||
if v < (2 << 31) {
|
|
||||||
w.write_all(&(v as u32).to_le_bytes())?;
|
|
||||||
return Ok(byte_count);
|
|
||||||
} else {
|
|
||||||
w.write_all(&(((v & 0x7fffffff) + (2 << 31)) as u32).to_le_bytes())?;
|
|
||||||
v = v >> 31;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn varint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<usize> {
|
pub fn varint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<usize> {
|
||||||
let mut byte_count = 0;
|
let mut byte_count = 0;
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -10,7 +10,6 @@ pub struct TestCases {
|
||||||
pub enum TestCase {
|
pub enum TestCase {
|
||||||
Test(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
Test(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
||||||
NondeterministicTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
NondeterministicTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
||||||
StreamingTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
|
||||||
DecodeTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
DecodeTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
|
||||||
ParseError(String),
|
ParseError(String),
|
||||||
ParseShort(String),
|
ParseShort(String),
|
||||||
|
|
|
@ -29,15 +29,11 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result<Vec<IOValue>, std::io::Error> {
|
||||||
assert_eq!(&PackedWriter::encode(val)?, bin);
|
assert_eq!(&PackedWriter::encode(val)?, bin);
|
||||||
}
|
}
|
||||||
TestCase::NondeterministicTest(ref bin, ref val) => {
|
TestCase::NondeterministicTest(ref bin, ref val) => {
|
||||||
// The test cases in samples.txt are carefully
|
// The test cases in samples.txt are carefully written
|
||||||
// written so that while strictly
|
// so that while strictly "nondeterministic", the
|
||||||
// "nondeterministic", the order of keys in
|
// order of keys in encoded dictionaries follows
|
||||||
// dictionaries follows Preserves order.
|
// Preserves canonical order.
|
||||||
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
|
||||||
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
|
||||||
assert_eq!(&PackedWriter::encode(val)?, bin);
|
assert_eq!(&PackedWriter::encode(val)?, bin);
|
||||||
}
|
|
||||||
TestCase::StreamingTest(ref bin, ref val) => {
|
|
||||||
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
||||||
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue