Embedded-parameterised Writer

This commit is contained in:
Tony Garnock-Jones 2021-07-05 12:34:29 +02:00
parent 8f1a83e548
commit da08189dd4
12 changed files with 200 additions and 150 deletions

View File

@ -151,7 +151,7 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
lines.push(format!(" use {}::support as _support;", &config.support_crate));
lines.push(" _support::lazy_static! {".to_owned());
for (value, name) in &m.literals {
let bs = preserves::value::PackedWriter::encode(&value).unwrap();
let bs = preserves::value::PackedWriter::encode_iovalue(&value).unwrap();
lines.push(format!(
" pub static ref {}: {} = /* {:?} */ _support::decode_lit(&vec!{:?}).unwrap();",
name,

View File

@ -6,7 +6,7 @@ use preserves::value::Embeddable;
use preserves::value::IOResult;
use preserves::value::IOValue;
use preserves::value::NestedValue;
use preserves::value::NoEmbeddedDomainDecode;
use preserves::value::NoEmbeddedDomainCodec;
use preserves::value::Value;
use std::convert::From;
@ -14,7 +14,7 @@ use std::convert::TryFrom;
use std::sync::Arc;
pub fn decode_lit<D: Embeddable, N: NestedValue<D>>(bs: &[u8]) -> IOResult<N> {
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainDecode)
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec)
}
pub fn decode_embedded<D: Domain>(

View File

@ -4,7 +4,7 @@ use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, Deseri
use std::borrow::Cow;
use std::marker::PhantomData;
use super::value::{IOValue, IOValueDomainDecode, PackedReader};
use super::value::{IOValue, IOValueDomainCodec, PackedReader};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
pub use super::error::Error;
@ -21,7 +21,7 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
where
T: Deserialize<'de>
{
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainDecode))
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainCodec))
}
pub fn from_read<'de, 'r, IOR: std::io::Read, T>(read: &'r mut IOR) ->
@ -29,7 +29,7 @@ pub fn from_read<'de, 'r, IOR: std::io::Read, T>(read: &'r mut IOR) ->
where
T: Deserialize<'de>
{
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainDecode))
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainCodec))
}
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue, IOValue>, T>(read: &'r mut R) ->

View File

@ -29,7 +29,7 @@ mod dom {
Value::Embedded(Dom::One).wrap(),
Value::from(2).wrap()])
.wrap();
assert_eq!(PackedWriter::encode(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
}
@ -38,7 +38,7 @@ mod dom {
Value::Embedded(Dom::Two).wrap(),
Value::from(2).wrap()])
.wrap();
assert_eq!(PackedWriter::encode(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
}
}
@ -465,7 +465,7 @@ mod serde_tests {
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let v_bytes_1 = PackedWriter::encode(&w).unwrap();
let v_bytes_1 = PackedWriter::encode_iovalue(&w).unwrap();
println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1);

View File

@ -1,4 +1,5 @@
use serde::Serialize;
use super::value::IOValueDomainCodec;
use super::value::writer::{Writer, CompoundWriter};
pub use super::error::Error;
@ -153,7 +154,7 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Result<Self::Ok> where T: Serialize
{
match super::value::magic::receive_output_value(name, value) {
Some(v) => Ok(self.write.write(&v)?),
Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(Some(1))?;

View File

@ -3,6 +3,7 @@ use super::Embeddable;
use super::IOResult;
use super::IOValue;
use super::Reader;
use super::Writer;
use super::packed::PackedReader;
pub trait DomainDecode<D: Embeddable> {
@ -13,21 +14,39 @@ pub trait DomainDecode<D: Embeddable> {
) -> IOResult<D>;
}
pub struct IOValueDomainDecode;
pub trait DomainEncode<D: Embeddable> {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &D,
) -> IOResult<()>;
}
impl DomainDecode<IOValue> for IOValueDomainDecode {
pub struct IOValueDomainCodec;
impl DomainDecode<IOValue> for IOValueDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
read_annotations: bool,
) -> IOResult<IOValue> {
PackedReader::new(src, IOValueDomainDecode).demand_next(read_annotations)
PackedReader::new(src, IOValueDomainCodec).demand_next(read_annotations)
}
}
pub struct NoEmbeddedDomainDecode;
impl DomainEncode<IOValue> for IOValueDomainCodec {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &IOValue,
) -> IOResult<()> {
w.write(self, d)
}
}
impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainDecode {
pub struct NoEmbeddedDomainCodec;
impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
_src: &'src mut S,
@ -36,3 +55,13 @@ impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainDecode {
Err(std::io::Error::new(std::io::ErrorKind::Unsupported, "Embedded values not supported here"))
}
}
impl<D: Embeddable> DomainEncode<D> for NoEmbeddedDomainCodec {
fn encode_embedded<W: Writer>(
&mut self,
_w: &mut W,
_d: &D,
) -> IOResult<()> {
Err(std::io::Error::new(std::io::ErrorKind::Unsupported, "Embedded values not supported here"))
}
}

View File

@ -11,8 +11,9 @@ pub mod writer;
pub use de::Deserializer;
pub use de::from_value;
pub use domain::DomainDecode;
pub use domain::IOValueDomainDecode;
pub use domain::NoEmbeddedDomainDecode;
pub use domain::DomainEncode;
pub use domain::IOValueDomainCodec;
pub use domain::NoEmbeddedDomainCodec;
pub use packed::PackedReader;
pub use packed::PackedWriter;
pub use reader::BinarySource;

View File

@ -5,7 +5,7 @@ pub mod writer;
pub use reader::PackedReader;
pub use writer::PackedWriter;
use super::{BinarySource, DomainDecode, Embeddable, IOResult, IOValue, IOValueDomainDecode, NestedValue, Reader};
use super::{BinarySource, DomainDecode, Embeddable, IOResult, IOValue, IOValueDomainCodec, NestedValue, Reader};
pub fn from_bytes<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>>(
bs: &[u8],
@ -15,7 +15,7 @@ pub fn from_bytes<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>>(
}
pub fn iovalue_from_bytes(bs: &[u8]) -> IOResult<IOValue> {
from_bytes(bs, IOValueDomainDecode)
from_bytes(bs, IOValueDomainCodec)
}
pub fn annotated_from_bytes<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<D>>(
@ -26,5 +26,5 @@ pub fn annotated_from_bytes<D: Embeddable, N: NestedValue<D>, Dec: DomainDecode<
}
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> IOResult<IOValue> {
annotated_from_bytes(bs, IOValueDomainDecode)
annotated_from_bytes(bs, IOValueDomainCodec)
}

View File

@ -4,9 +4,14 @@ use std::convert::TryInto;
use std::mem;
use std::ops::{Deref, DerefMut};
use super::constants::Tag;
use super::super::DomainEncode;
use super::super::Embeddable;
use super::super::IOValue;
use super::super::IOValueDomainCodec;
use super::super::IOResult;
use super::super::NestedValue;
use super::super::writer::{Writer, AnnotationWriter, CompoundWriter, Result, varint};
use super::super::writer::{Writer, AnnotationWriter, CompoundWriter, varint};
pub enum Suspendable<T> {
Active(T),
@ -70,12 +75,19 @@ impl<T> DerefMut for Suspendable<T> {
pub struct PackedWriter<W: std::io::Write>(Suspendable<W>);
impl PackedWriter<Vec<u8>> {
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> {
pub fn encode<D: Embeddable, N: NestedValue<D>, Enc: DomainEncode<D>>(
enc: &mut Enc,
v: &N,
) -> IOResult<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new();
let w = &mut PackedWriter::new(&mut buf);
w.write(v)?;
w.write(enc, v)?;
Ok(buf)
}
pub fn encode_iovalue(v: &IOValue) -> std::io::Result<Vec<u8>> {
Self::encode(&mut IOValueDomainCodec, v)
}
}
impl<W: std::io::Write> PackedWriter<W> {
@ -87,18 +99,18 @@ impl<W: std::io::Write> PackedWriter<W> {
self.0.deref_mut()
}
pub fn write_byte(&mut self, b: u8) -> Result<()> {
pub fn write_byte(&mut self, b: u8) -> IOResult<()> {
self.w().write_all(&[b])
}
pub fn write_medium_integer(&mut self, bs: &[u8]) -> Result<()> {
pub fn write_medium_integer(&mut self, bs: &[u8]) -> IOResult<()> {
let count: u8 = bs.len().try_into().unwrap();
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) }
self.write_byte(Tag::MediumInteger(count).into())?;
self.w().write_all(bs)
}
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> Result<()> {
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> IOResult<()> {
self.write_byte(tag.into())?;
varint(&mut self.w(), bs.len().try_into().unwrap())?;
self.w().write_all(bs)
@ -140,7 +152,7 @@ impl BinaryOrderWriter {
self.0.last_mut().unwrap()
}
fn finish<W: WriteWriter>(mut self, w: &mut W) -> Result<()> {
fn finish<W: WriteWriter>(mut self, w: &mut W) -> IOResult<()> {
if !self.buffer().is_empty() { panic!("Missing final delimit()"); }
self.items_mut().pop();
self.items_mut().sort();
@ -153,51 +165,51 @@ impl BinaryOrderWriter {
}
pub trait WriteWriter: Writer {
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()>;
fn write_tag(&mut self, tag: Tag) -> Result<()> {
fn write_raw_bytes(&mut self, v: &[u8]) -> IOResult<()>;
fn write_tag(&mut self, tag: Tag) -> IOResult<()> {
self.write_raw_bytes(&[tag.into()])
}
}
impl<W: std::io::Write> WriteWriter for PackedWriter<W> {
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> {
fn write_raw_bytes(&mut self, v: &[u8]) -> IOResult<()> {
self.w().write_all(v)
}
}
impl WriteWriter for BinaryOrderWriter {
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> {
fn write_raw_bytes(&mut self, v: &[u8]) -> IOResult<()> {
use std::io::Write;
self.buffer().write_all(v)
}
}
impl<T: WriteWriter> AnnotationWriter for T {
fn start_annotation(&mut self) -> Result<()> {
fn start_annotation(&mut self) -> IOResult<()> {
Ok(self.write_tag(Tag::Annotation)?)
}
fn start_value(&mut self) -> Result<()> {
fn start_value(&mut self) -> IOResult<()> {
Ok(())
}
}
impl<W: std::io::Write> CompoundWriter for PackedWriter<W> {
fn extend(&mut self) -> Result<()> {
fn extend(&mut self) -> IOResult<()> {
Ok(())
}
fn delimit(&mut self) -> Result<()> {
fn delimit(&mut self) -> IOResult<()> {
Ok(())
}
}
impl CompoundWriter for BinaryOrderWriter {
fn extend(&mut self) -> Result<()> {
fn extend(&mut self) -> IOResult<()> {
Ok(())
}
fn delimit(&mut self) -> Result<()> {
fn delimit(&mut self) -> IOResult<()> {
self.items_mut().push(vec![]);
Ok(())
}
@ -216,67 +228,67 @@ impl Writer for BinaryOrderWriter {
type SetWriter = BinaryOrderWriter;
type EmbeddedWriter = PackedWriter<Vec<u8>>;
binary_order_writer_method!(mut align(natural_chunksize: u64) -> Result<()>);
binary_order_writer_method!(mut align(natural_chunksize: u64) -> IOResult<()>);
fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
fn start_annotations(&mut self) -> IOResult<Self::AnnWriter> {
Ok(self.pop())
}
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
fn end_annotations(&mut self, ann: Self::AnnWriter) -> IOResult<()> {
self.push(ann);
Ok(())
}
binary_order_writer_method!(mut write_bool(v: bool) -> Result<()>);
binary_order_writer_method!(mut write_bool(v: bool) -> IOResult<()>);
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_f32(v: f32) -> IOResult<()>);
binary_order_writer_method!(mut write_f64(v: f64) -> IOResult<()>);
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_i8(v: i8) -> IOResult<()>);
binary_order_writer_method!(mut write_u8(v: u8) -> IOResult<()>);
binary_order_writer_method!(mut write_i16(v: i16) -> IOResult<()>);
binary_order_writer_method!(mut write_u16(v: u16) -> IOResult<()>);
binary_order_writer_method!(mut write_i32(v: i32) -> IOResult<()>);
binary_order_writer_method!(mut write_u32(v: u32) -> IOResult<()>);
binary_order_writer_method!(mut write_i64(v: i64) -> IOResult<()>);
binary_order_writer_method!(mut write_u64(v: u64) -> IOResult<()>);
binary_order_writer_method!(mut write_i128(v: i128) -> IOResult<()>);
binary_order_writer_method!(mut write_u128(v: u128) -> IOResult<()>);
binary_order_writer_method!(mut write_int(v: &BigInt) -> IOResult<()>);
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<()>);
binary_order_writer_method!(mut write_string(v: &str) -> IOResult<()>);
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> IOResult<()>);
binary_order_writer_method!(mut write_symbol(v: &str) -> IOResult<()>);
fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
fn start_record(&mut self, _field_count: Option<usize>) -> IOResult<Self::SeqWriter> {
self.write_tag(Tag::Record)?;
Ok(self.pop())
}
fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
fn start_sequence(&mut self, _item_count: Option<usize>) -> IOResult<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.pop())
}
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
fn end_seq(&mut self, seq: Self::SeqWriter) -> IOResult<()> {
self.push(seq);
self.write_tag(Tag::End)
}
fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
fn start_set(&mut self, _item_count: Option<usize>) -> IOResult<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> IOResult<Self::SetWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
fn end_set(&mut self, set: Self::SetWriter) -> IOResult<()> {
set.finish(self)
}
fn start_embedded(&mut self) -> Result<Self::EmbeddedWriter> {
fn start_embedded(&mut self) -> IOResult<Self::EmbeddedWriter> {
self.write_tag(Tag::Embedded)?;
Ok(self.pop())
}
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> Result<()> {
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> IOResult<()> {
self.push(ptr);
Ok(())
}
@ -296,54 +308,54 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
type SetWriter = BinaryOrderWriter;
type EmbeddedWriter = Self;
fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
fn start_annotations(&mut self) -> IOResult<Self::AnnWriter> {
Ok(self.suspend())
}
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
fn end_annotations(&mut self, ann: Self::AnnWriter) -> IOResult<()> {
self.resume(ann);
Ok(())
}
fn align(&mut self, _natural_chunksize: u64) -> Result<()> {
fn align(&mut self, _natural_chunksize: u64) -> IOResult<()> {
Ok(())
}
fn write_bool(&mut self, v: bool) -> Result<()> {
fn write_bool(&mut self, v: bool) -> IOResult<()> {
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) -> IOResult<()> {
self.write_tag(Tag::Float)?;
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) -> IOResult<()> {
self.write_tag(Tag::Double)?;
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) -> IOResult<()> {
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
self.write_medium_integer(&[v as u8])
}
fn write_u8(&mut self, v: u8) -> Result<()> {
fn write_u8(&mut self, v: u8) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) }
self.write_medium_integer(&[0, v])
}
fn write_i16(&mut self, v: i16) -> Result<()> {
fn write_i16(&mut self, v: i16) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) }
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) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) }
self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
}
fn write_i32(&mut self, v: i32) -> Result<()> {
fn write_i32(&mut self, v: i32) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) }
if fits_in_bytes!(v, 3) {
return self.write_medium_integer(&[(v >> 16) as u8,
@ -356,7 +368,7 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
(v & 255) as u8])
}
fn write_u32(&mut self, v: u32) -> Result<()> {
fn write_u32(&mut self, v: u32) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
self.write_medium_integer(&[0,
(v >> 24) as u8,
@ -365,7 +377,7 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
(v & 255) as u8])
}
fn write_i64(&mut self, v: i64) -> Result<()> {
fn write_i64(&mut self, v: i64) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
if fits_in_bytes!(v, 5) {
return self.write_medium_integer(&[(v >> 32) as u8,
@ -401,7 +413,7 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
(v & 255) as u8])
}
fn write_u64(&mut self, v: u64) -> Result<()> {
fn write_u64(&mut self, v: u64) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) }
self.write_medium_integer(&[0,
(v >> 56) as u8,
@ -414,7 +426,7 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
(v & 255) as u8])
}
fn write_i128(&mut self, v: i128) -> Result<()> {
fn write_i128(&mut self, v: i128) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) }
let bs: [u8; 16] = v.to_be_bytes();
if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); }
@ -427,7 +439,7 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
self.write_medium_integer(&bs)
}
fn write_u128(&mut self, v: u128) -> Result<()> {
fn write_u128(&mut self, v: u128) -> IOResult<()> {
if let Ok(w) = v.try_into() { return self.write_i128(w) }
let bs: [u8; 16] = v.to_be_bytes();
self.write_tag(Tag::SignedInteger)?;
@ -436,7 +448,7 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
self.write_raw_bytes(&bs)
}
fn write_int(&mut self, v: &BigInt) -> Result<()> {
fn write_int(&mut self, v: &BigInt) -> IOResult<()> {
match v.to_i8() {
Some(n) => self.write_i8(n),
None => {
@ -448,53 +460,53 @@ impl<W: std::io::Write> Writer for PackedWriter<W>
}
}
fn write_string(&mut self, v: &str) -> Result<()> {
fn write_string(&mut self, v: &str) -> IOResult<()> {
self.write_atom(Tag::String, v.as_bytes())
}
fn write_bytes(&mut self, v: &[u8]) -> Result<()> {
fn write_bytes(&mut self, v: &[u8]) -> IOResult<()> {
self.write_atom(Tag::ByteString, v)
}
fn write_symbol(&mut self, v: &str) -> Result<()> {
fn write_symbol(&mut self, v: &str) -> IOResult<()> {
self.write_atom(Tag::Symbol, v.as_bytes())
}
fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
fn start_record(&mut self, _field_count: Option<usize>) -> IOResult<Self::SeqWriter> {
self.write_tag(Tag::Record)?;
Ok(self.suspend())
}
fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
fn start_sequence(&mut self, _item_count: Option<usize>) -> IOResult<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.suspend())
}
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
fn end_seq(&mut self, seq: Self::SeqWriter) -> IOResult<()> {
self.resume(seq);
self.write_tag(Tag::End)
}
fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
fn start_set(&mut self, _item_count: Option<usize>) -> IOResult<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> IOResult<Self::SetWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
fn end_set(&mut self, set: Self::SetWriter) -> IOResult<()> {
set.finish(self)
}
fn start_embedded(&mut self) -> Result<Self::EmbeddedWriter> {
fn start_embedded(&mut self) -> IOResult<Self::EmbeddedWriter> {
self.write_tag(Tag::Embedded)?;
Ok(self.suspend())
}
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> Result<()> {
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> IOResult<()> {
self.resume(ann);
Ok(())
}

View File

@ -4,7 +4,7 @@ use std::borrow::Cow;
use std::io::Read;
use std::marker::PhantomData;
use super::{DomainDecode, Embeddable, IOResult, IOValue, IOValueDomainDecode, NestedValue};
use super::{DomainDecode, Embeddable, IOResult, IOValue, IOValueDomainCodec, NestedValue};
pub type ReaderResult<T> = std::result::Result<T, error::Error>;
@ -173,9 +173,9 @@ pub trait BinarySource<'de>: Sized {
}
fn packed_iovalues(&mut self) ->
super::PackedReader<'de, '_, IOValue, IOValue, IOValueDomainDecode, Self>
super::PackedReader<'de, '_, IOValue, IOValue, IOValueDomainCodec, Self>
{
self.packed(IOValueDomainDecode)
self.packed(IOValueDomainCodec)
}
}

View File

@ -1,18 +1,17 @@
use num::bigint::BigInt;
use std::io::Error;
use super::DomainEncode;
use super::IOResult;
use super::signed_integer::SignedIntegerRepr;
use super::repr::{Value, NestedValue, IOValue, UnwrappedIOValue, Float, Double};
pub type Result<T> = std::result::Result<T, Error>;
use super::repr::{Embeddable, Value, NestedValue, Float, Double};
pub trait AnnotationWriter: Writer {
fn start_annotation(&mut self) -> Result<()>;
fn start_value(&mut self) -> Result<()>;
fn start_annotation(&mut self) -> IOResult<()>;
fn start_value(&mut self) -> IOResult<()>;
}
pub trait CompoundWriter: Writer {
fn extend(&mut self) -> Result<()>;
fn delimit(&mut self) -> Result<()>;
fn extend(&mut self) -> IOResult<()>;
fn delimit(&mut self) -> IOResult<()>;
}
pub trait Writer: Sized {
@ -21,65 +20,73 @@ pub trait Writer: Sized {
type SetWriter: CompoundWriter;
type EmbeddedWriter: Writer;
fn align(&mut self, natural_chunksize: u64) -> Result<()>;
fn align(&mut self, natural_chunksize: u64) -> IOResult<()>;
fn start_annotations(&mut self) -> Result<Self::AnnWriter>;
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()>;
fn start_annotations(&mut self) -> IOResult<Self::AnnWriter>;
fn end_annotations(&mut self, ann: Self::AnnWriter) -> IOResult<()>;
fn write_bool(&mut self, v: bool) -> Result<()>;
fn write_bool(&mut self, v: bool) -> IOResult<()>;
fn write_f32(&mut self, v: f32) -> Result<()>;
fn write_f64(&mut self, v: f64) -> Result<()>;
fn write_f32(&mut self, v: f32) -> IOResult<()>;
fn write_f64(&mut self, v: f64) -> IOResult<()>;
fn write_i8(&mut self, v: i8) -> Result<()>;
fn write_u8(&mut self, v: u8) -> Result<()>;
fn write_i16(&mut self, v: i16) -> Result<()>;
fn write_u16(&mut self, v: u16) -> Result<()>;
fn write_i32(&mut self, v: i32) -> Result<()>;
fn write_u32(&mut self, v: u32) -> Result<()>;
fn write_i64(&mut self, v: i64) -> Result<()>;
fn write_u64(&mut self, v: u64) -> Result<()>;
fn write_i128(&mut self, v: i128) -> Result<()>;
fn write_u128(&mut self, v: u128) -> Result<()>;
fn write_int(&mut self, v: &BigInt) -> Result<()>;
fn write_i8(&mut self, v: i8) -> IOResult<()>;
fn write_u8(&mut self, v: u8) -> IOResult<()>;
fn write_i16(&mut self, v: i16) -> IOResult<()>;
fn write_u16(&mut self, v: u16) -> IOResult<()>;
fn write_i32(&mut self, v: i32) -> IOResult<()>;
fn write_u32(&mut self, v: u32) -> IOResult<()>;
fn write_i64(&mut self, v: i64) -> IOResult<()>;
fn write_u64(&mut self, v: u64) -> IOResult<()>;
fn write_i128(&mut self, v: i128) -> IOResult<()>;
fn write_u128(&mut self, v: u128) -> IOResult<()>;
fn write_int(&mut self, v: &BigInt) -> IOResult<()>;
fn write_string(&mut self, v: &str) -> Result<()>;
fn write_bytes(&mut self, v: &[u8]) -> Result<()>;
fn write_symbol(&mut self, v: &str) -> Result<()>;
fn write_string(&mut self, v: &str) -> IOResult<()>;
fn write_bytes(&mut self, v: &[u8]) -> IOResult<()>;
fn write_symbol(&mut self, v: &str) -> IOResult<()>;
fn start_record(&mut self, field_count: Option<usize>) -> Result<Self::SeqWriter>;
fn start_sequence(&mut self, item_count: Option<usize>) -> Result<Self::SeqWriter>;
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()>;
fn start_record(&mut self, field_count: Option<usize>) -> IOResult<Self::SeqWriter>;
fn start_sequence(&mut self, item_count: Option<usize>) -> IOResult<Self::SeqWriter>;
fn end_seq(&mut self, seq: Self::SeqWriter) -> IOResult<()>;
fn start_set(&mut self, item_count: Option<usize>) -> Result<Self::SetWriter>;
fn start_dictionary(&mut self, entry_count: Option<usize>) -> Result<Self::SetWriter>;
fn end_set(&mut self, set: Self::SetWriter) -> Result<()>;
fn start_set(&mut self, item_count: Option<usize>) -> IOResult<Self::SetWriter>;
fn start_dictionary(&mut self, entry_count: Option<usize>) -> IOResult<Self::SetWriter>;
fn end_set(&mut self, set: Self::SetWriter) -> IOResult<()>;
fn start_embedded(&mut self) -> Result<Self::EmbeddedWriter>;
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> Result<()>;
fn start_embedded(&mut self) -> IOResult<Self::EmbeddedWriter>;
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> IOResult<()>;
//---------------------------------------------------------------------------
fn write(&mut self, v: &IOValue) -> Result<()> {
fn write<D: Embeddable, N: NestedValue<D>, Enc: DomainEncode<D>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> IOResult<()> {
match v.annotations().maybe_slice() {
None => {
self.write_value(v.value())?;
self.write_value(enc, v.value())?;
}
Some(anns) => {
let mut a = self.start_annotations()?;
for ann in anns {
a.start_annotation()?;
a.write(ann)?;
a.write(enc, ann)?;
}
a.start_value()?;
a.write_value(v.value())?;
a.write_value(enc, v.value())?;
self.end_annotations(a)?;
}
}
Ok(())
}
fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<()> {
fn write_value<D: Embeddable, N: NestedValue<D>, Enc: DomainEncode<D>>(
&mut self,
enc: &mut Enc,
v: &Value<N, D>,
) -> IOResult<()> {
match v {
Value::Boolean(b) => self.write_bool(*b),
Value::Float(Float(f)) => self.write_f32(*f),
@ -95,11 +102,11 @@ pub trait Writer: Sized {
Value::Record(r) => {
let mut c = self.start_record(Some(r.arity()))?;
c.extend()?;
c.write(r.label())?;
c.write(enc, r.label())?;
c.delimit()?;
for f in r.fields() {
c.extend()?;
c.write(f)?;
c.write(enc, f)?;
c.delimit()?;
}
self.end_seq(c)
@ -108,7 +115,7 @@ pub trait Writer: Sized {
let mut c = self.start_sequence(Some(vs.len()))?;
for v in vs {
c.extend()?;
c.write(v)?;
c.write(enc, v)?;
c.delimit()?;
}
self.end_seq(c)
@ -117,7 +124,7 @@ pub trait Writer: Sized {
let mut c = self.start_set(Some(vs.len()))?;
for v in vs {
c.extend()?;
c.write(v)?;
c.write(enc, v)?;
c.delimit()?;
}
self.end_set(c)
@ -126,22 +133,22 @@ pub trait Writer: Sized {
let mut c = self.start_dictionary(Some(vs.len()))?;
for (k, v) in vs {
c.extend()?;
c.write(k)?;
c.write(v)?;
c.write(enc, k)?;
c.write(enc, v)?;
c.delimit()?;
}
self.end_set(c)
}
Value::Embedded(d) => {
let mut c = self.start_embedded()?;
c.write(&d)?;
enc.encode_embedded(&mut c, d)?;
self.end_embedded(c)
}
}
}
}
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) -> IOResult<usize> {
let mut byte_count = 0;
loop {
byte_count += 1;

View File

@ -27,21 +27,21 @@ fn decode_all(bytes: &'_ [u8]) -> Result<Vec<IOValue>, std::io::Error> {
println!("{:?} ==> {:?}", name, case);
match case {
TestCase::Test(ref bin, ref val) => {
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&PackedWriter::encode_iovalue(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
assert_eq!(&PackedWriter::encode(val)?, bin);
assert_eq!(&PackedWriter::encode_iovalue(val)?, bin);
}
TestCase::NondeterministicTest(ref bin, ref val) => {
// The test cases in samples.pr are carefully written
// so that while strictly "nondeterministic", the
// order of keys in encoded dictionaries follows
// Preserves canonical order.
assert_eq!(&PackedWriter::encode(val)?, bin);
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
assert_eq!(&PackedWriter::encode_iovalue(val)?, bin);
assert_eq!(&decode_all(&PackedWriter::encode_iovalue(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
}
TestCase::DecodeTest(ref bin, ref val) => {
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&PackedWriter::encode_iovalue(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
}
TestCase::ParseError(_) => (),