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(format!(" use {}::support as _support;", &config.support_crate));
lines.push(" _support::lazy_static! {".to_owned()); lines.push(" _support::lazy_static! {".to_owned());
for (value, name) in &m.literals { 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!( lines.push(format!(
" pub static ref {}: {} = /* {:?} */ _support::decode_lit(&vec!{:?}).unwrap();", " pub static ref {}: {} = /* {:?} */ _support::decode_lit(&vec!{:?}).unwrap();",
name, name,

View File

@ -6,7 +6,7 @@ use preserves::value::Embeddable;
use preserves::value::IOResult; use preserves::value::IOResult;
use preserves::value::IOValue; use preserves::value::IOValue;
use preserves::value::NestedValue; use preserves::value::NestedValue;
use preserves::value::NoEmbeddedDomainDecode; use preserves::value::NoEmbeddedDomainCodec;
use preserves::value::Value; use preserves::value::Value;
use std::convert::From; use std::convert::From;
@ -14,7 +14,7 @@ use std::convert::TryFrom;
use std::sync::Arc; use std::sync::Arc;
pub fn decode_lit<D: Embeddable, N: NestedValue<D>>(bs: &[u8]) -> IOResult<N> { pub fn decode_lit<D: Embeddable, N: NestedValue<D>>(bs: &[u8]) -> IOResult<N> {
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainDecode) preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec)
} }
pub fn decode_embedded<D: Domain>( 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::borrow::Cow;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::value::{IOValue, IOValueDomainDecode, PackedReader}; use super::value::{IOValue, IOValueDomainCodec, PackedReader};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource}; use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
pub use super::error::Error; pub use super::error::Error;
@ -21,7 +21,7 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
where where
T: Deserialize<'de> T: Deserialize<'de>
{ {
from_reader(&mut PackedReader::new(&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) -> 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 where
T: Deserialize<'de> 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) -> 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::Embedded(Dom::One).wrap(),
Value::from(2).wrap()]) Value::from(2).wrap()])
.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]); [0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
} }
@ -38,7 +38,7 @@ mod dom {
Value::Embedded(Dom::Two).wrap(), Value::Embedded(Dom::Two).wrap(),
Value::from(2).wrap()]) Value::from(2).wrap()])
.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]); [0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
} }
} }
@ -465,7 +465,7 @@ mod serde_tests {
println!("== y: {:#?}", &y); println!("== y: {:#?}", &y);
assert_eq!(v, 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); println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1); assert_eq!(expected_bytes, v_bytes_1);

View File

@ -1,4 +1,5 @@
use serde::Serialize; use serde::Serialize;
use super::value::IOValueDomainCodec;
use super::value::writer::{Writer, CompoundWriter}; use super::value::writer::{Writer, CompoundWriter};
pub use super::error::Error; 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 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) => Ok(self.write.write(&v)?), Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
None => { None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`? // TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(Some(1))?; let mut c = self.write.start_record(Some(1))?;

View File

@ -3,6 +3,7 @@ use super::Embeddable;
use super::IOResult; use super::IOResult;
use super::IOValue; use super::IOValue;
use super::Reader; use super::Reader;
use super::Writer;
use super::packed::PackedReader; use super::packed::PackedReader;
pub trait DomainDecode<D: Embeddable> { pub trait DomainDecode<D: Embeddable> {
@ -13,21 +14,39 @@ pub trait DomainDecode<D: Embeddable> {
) -> IOResult<D>; ) -> 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>>( fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self, &mut self,
src: &'src mut S, src: &'src mut S,
read_annotations: bool, read_annotations: bool,
) -> IOResult<IOValue> { ) -> 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>>( fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self, &mut self,
_src: &'src mut S, _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")) 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::Deserializer;
pub use de::from_value; pub use de::from_value;
pub use domain::DomainDecode; pub use domain::DomainDecode;
pub use domain::IOValueDomainDecode; pub use domain::DomainEncode;
pub use domain::NoEmbeddedDomainDecode; pub use domain::IOValueDomainCodec;
pub use domain::NoEmbeddedDomainCodec;
pub use packed::PackedReader; pub use packed::PackedReader;
pub use packed::PackedWriter; pub use packed::PackedWriter;
pub use reader::BinarySource; pub use reader::BinarySource;

View File

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

View File

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

View File

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