More boulder-pushing
This commit is contained in:
parent
4070c5252d
commit
025c5bb962
|
@ -1,17 +1,15 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use super::IOValue;
|
|
||||||
use super::Reader;
|
use super::Reader;
|
||||||
use super::Writer;
|
use super::Writer;
|
||||||
use super::ValueImpl;
|
|
||||||
|
|
||||||
pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone + 'static {
|
pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone {
|
||||||
type Decode: DomainDecode<Self> + Default;
|
type Decode: for<'de> DomainDecode<'de, Self> + Default;
|
||||||
type Encode: DomainEncode<Self> + Default;
|
type Encode: DomainEncode<Self> + Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DomainDecode<D: Domain> {
|
pub trait DomainDecode<'de, D: Domain> {
|
||||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
read_annotations: bool,
|
read_annotations: bool,
|
||||||
|
@ -26,8 +24,8 @@ pub trait DomainEncode<D: Domain> {
|
||||||
) -> io::Result<()>;
|
) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D: Domain, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
|
impl<'a, 'de, D: Domain, T: DomainDecode<'de, D>> DomainDecode<'de, D> for &'a mut T {
|
||||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
read_annotations: bool,
|
read_annotations: bool,
|
||||||
|
@ -49,8 +47,8 @@ impl<'a, D: Domain, T: DomainEncode<D>> DomainEncode<D> for &'a mut T {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DefaultDomainCodec;
|
pub struct DefaultDomainCodec;
|
||||||
|
|
||||||
impl<D: Domain> DomainDecode<D> for DefaultDomainCodec {
|
impl<'de, D: Domain> DomainDecode<'de, D> for DefaultDomainCodec {
|
||||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
read_annotations: bool,
|
read_annotations: bool,
|
||||||
|
@ -72,8 +70,8 @@ impl<D: Domain> DomainEncode<D> for DefaultDomainCodec {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DebugDomainCodec;
|
pub struct DebugDomainCodec;
|
||||||
|
|
||||||
impl<Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<D> for DebugDomainCodec {
|
impl<'de, Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<'de, D> for DebugDomainCodec {
|
||||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
_read_annotations: bool,
|
_read_annotations: bool,
|
||||||
|
@ -95,8 +93,8 @@ impl<D: Domain> DomainEncode<D> for DebugDomainCodec {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct NoEmbeddedDomainCodec;
|
pub struct NoEmbeddedDomainCodec;
|
||||||
|
|
||||||
impl<D: Domain> DomainDecode<D> for NoEmbeddedDomainCodec {
|
impl<'de, D: Domain> DomainDecode<'de, D> for NoEmbeddedDomainCodec {
|
||||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_r: &mut R,
|
_r: &mut R,
|
||||||
_read_annotations: bool,
|
_read_annotations: bool,
|
||||||
|
@ -114,26 +112,3 @@ impl<D: Domain> DomainEncode<D> for NoEmbeddedDomainCodec {
|
||||||
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
|
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct IOValueDomainCodec;
|
|
||||||
|
|
||||||
impl DomainDecode<IOValue> for IOValueDomainCodec {
|
|
||||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
|
||||||
&mut self,
|
|
||||||
r: &mut R,
|
|
||||||
read_annotations: bool,
|
|
||||||
) -> io::Result<IOValue> {
|
|
||||||
Ok(read_iovalue(r, read_annotations)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DomainEncode<IOValue> for IOValueDomainCodec {
|
|
||||||
fn encode_embedded(
|
|
||||||
&mut self,
|
|
||||||
w: &mut dyn Writer,
|
|
||||||
d: &IOValue,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
d.write(w, self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,6 +36,12 @@ pub enum ExpectedKind {
|
||||||
Annotation,
|
Annotation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ReadError {
|
||||||
|
UnsupportedFormat,
|
||||||
|
Io(io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ExpectedKind> for Error {
|
impl From<ExpectedKind> for Error {
|
||||||
fn from(e: ExpectedKind) -> Self {
|
fn from(e: ExpectedKind) -> Self {
|
||||||
Error::Expected(e)
|
Error::Expected(e)
|
||||||
|
@ -48,6 +54,39 @@ impl From<io::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ReadError> for Error {
|
||||||
|
fn from(e: ReadError) -> Self {
|
||||||
|
match e {
|
||||||
|
ReadError::UnsupportedFormat => Error::Message(format!("{}", e)),
|
||||||
|
ReadError::Io(i) => Error::Io(i),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ReadError> for io::Error {
|
||||||
|
fn from(e: ReadError) -> Self {
|
||||||
|
match e {
|
||||||
|
ReadError::UnsupportedFormat => Error::from(e).into(),
|
||||||
|
ReadError::Io(i) => i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for ReadError {
|
||||||
|
fn from(e: io::Error) -> Self {
|
||||||
|
ReadError::Io(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ReadError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
ReadError::UnsupportedFormat => write!(f, "Unsupported Preserves format"),
|
||||||
|
ReadError::Io(i) => write!(f, "{}", i),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Error> for io::Error {
|
impl From<Error> for io::Error {
|
||||||
fn from(e: Error) -> Self {
|
fn from(e: Error) -> Self {
|
||||||
match e {
|
match e {
|
||||||
|
@ -58,6 +97,8 @@ impl From<Error> for io::Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for ExpectedKind {}
|
||||||
|
impl std::error::Error for ReadError {}
|
||||||
impl std::error::Error for Error {}
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
|
@ -66,6 +107,12 @@ impl std::fmt::Display for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ExpectedKind {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn io_eof() -> io::Error {
|
pub fn io_eof() -> io::Error {
|
||||||
io::Error::new(io::ErrorKind::UnexpectedEof, "EOF")
|
io::Error::new(io::ErrorKind::UnexpectedEof, "EOF")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
use std::io;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::DomainDecode;
|
||||||
|
use crate::Reader;
|
||||||
|
use crate::DomainEncode;
|
||||||
|
use crate::ValueImpl;
|
||||||
|
use crate::Writer;
|
||||||
|
use crate::ValueReader;
|
||||||
|
|
||||||
|
pub struct IOValueDomainDecode<V: ValueReader>(PhantomData<V>);
|
||||||
|
pub struct IOValueDomainEncode<V: ValueImpl>(PhantomData<V>);
|
||||||
|
|
||||||
|
impl<V: ValueReader> Default for IOValueDomainDecode<V> { fn default() -> Self { Self(PhantomData) } }
|
||||||
|
impl<V: ValueImpl> Default for IOValueDomainEncode<V> { fn default() -> Self { Self(PhantomData) } }
|
||||||
|
|
||||||
|
impl<'de, V: ValueReader> DomainDecode<'de, <V::Impl<'de> as ValueImpl>::IOEmbedded> for IOValueDomainDecode<V> {
|
||||||
|
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||||
|
&mut self,
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
) -> io::Result<<V::Impl<'de> as ValueImpl>::IOEmbedded> {
|
||||||
|
Ok(V::read_iovalue(r, read_annotations)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: ValueImpl> DomainEncode<V::IOEmbedded> for IOValueDomainEncode<V> {
|
||||||
|
fn encode_embedded(
|
||||||
|
&mut self,
|
||||||
|
w: &mut dyn Writer,
|
||||||
|
d: &V::IOEmbedded,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
d.as_ref().borrow().write(w, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IOValues<'de, V: ValueReader, R: Reader<'de>> {
|
||||||
|
pub reader: R,
|
||||||
|
pub read_annotations: bool,
|
||||||
|
phantom: PhantomData<&'de V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, V: ValueReader, R: Reader<'de>> IOValues<'de, V, R> {
|
||||||
|
pub fn new(reader: R) -> Self {
|
||||||
|
IOValues {
|
||||||
|
reader,
|
||||||
|
read_annotations: false,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_annotations(mut self, read_annotations: bool) -> Self {
|
||||||
|
self.read_annotations = read_annotations;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, V: ValueReader, R: Reader<'de>> Iterator for IOValues<'de, V, R> {
|
||||||
|
type Item = io::Result<<V::Impl<'de> as ValueImpl>::IOEmbedded>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
match self.reader.peek_class() {
|
||||||
|
Err(e) => Some(Err(e)),
|
||||||
|
Ok(None) => None,
|
||||||
|
Ok(Some(_)) => match V::read_iovalue(&mut self.reader, self.read_annotations) {
|
||||||
|
Ok(v) => Some(Ok(v)),
|
||||||
|
Err(e) => Some(Err(e.into())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ pub mod domain;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod float;
|
pub mod float;
|
||||||
pub mod hex;
|
pub mod hex;
|
||||||
|
pub mod iovalue;
|
||||||
pub mod merge;
|
pub mod merge;
|
||||||
pub mod packed;
|
pub mod packed;
|
||||||
pub mod reader;
|
pub mod reader;
|
||||||
|
@ -10,26 +11,25 @@ pub mod repr;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
pub mod signed_integer;
|
pub mod signed_integer;
|
||||||
pub mod source;
|
pub mod source;
|
||||||
// pub mod text;
|
pub mod text;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
pub mod writer;
|
pub mod writer;
|
||||||
|
|
||||||
pub use domain::*;
|
pub use domain::*;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use error::ExpectedKind;
|
pub use error::ExpectedKind;
|
||||||
|
pub use iovalue::IOValueDomainDecode;
|
||||||
|
pub use iovalue::IOValueDomainEncode;
|
||||||
|
pub use iovalue::IOValues;
|
||||||
pub use merge::merge;
|
pub use merge::merge;
|
||||||
pub use merge::merge2;
|
pub use merge::merge2;
|
||||||
pub use packed::PackedReader;
|
pub use packed::PackedReader;
|
||||||
pub use packed::PackedWriter;
|
pub use packed::PackedWriter;
|
||||||
pub use packed::annotated_from_bytes;
|
pub use packed::annotated_from_bytes;
|
||||||
pub use packed::annotated_iovalue_from_bytes;
|
|
||||||
pub use packed::from_bytes;
|
pub use packed::from_bytes;
|
||||||
pub use packed::iovalue_from_bytes;
|
|
||||||
pub use reader::IOValues;
|
|
||||||
pub use reader::Reader;
|
pub use reader::Reader;
|
||||||
pub use reader::read;
|
|
||||||
pub use reader::read_iovalue;
|
|
||||||
pub use repr::ValueImpl;
|
pub use repr::ValueImpl;
|
||||||
|
pub use repr::ValueReader;
|
||||||
pub use repr::value_eq;
|
pub use repr::value_eq;
|
||||||
pub use repr::value_cmp;
|
pub use repr::value_cmp;
|
||||||
pub use repr::value_hash;
|
pub use repr::value_hash;
|
||||||
|
@ -45,12 +45,10 @@ pub use signed_integer::SignedInteger;
|
||||||
pub use source::BinarySource;
|
pub use source::BinarySource;
|
||||||
pub use source::BytesBinarySource;
|
pub use source::BytesBinarySource;
|
||||||
pub use source::IOBinarySource;
|
pub use source::IOBinarySource;
|
||||||
// pub use text::TextReader;
|
pub use text::TextReader;
|
||||||
// pub use text::TextWriter;
|
pub use text::TextWriter;
|
||||||
// pub use text::annotated_from_str;
|
pub use text::annotated_from_str;
|
||||||
// pub use text::annotated_iovalue_from_str;
|
pub use text::from_str;
|
||||||
// pub use text::from_str;
|
|
||||||
// pub use text::iovalue_from_str;
|
|
||||||
pub use types::AtomClass;
|
pub use types::AtomClass;
|
||||||
pub use types::CompoundClass;
|
pub use types::CompoundClass;
|
||||||
pub use types::ValueClass;
|
pub use types::ValueClass;
|
||||||
|
|
|
@ -12,29 +12,20 @@ use crate::BinarySource;
|
||||||
use crate::BytesBinarySource;
|
use crate::BytesBinarySource;
|
||||||
use crate::Domain;
|
use crate::Domain;
|
||||||
use crate::DomainDecode;
|
use crate::DomainDecode;
|
||||||
use crate::IOValue;
|
use crate::Shell;
|
||||||
use crate::ShellHandle;
|
use crate::ShellHandle;
|
||||||
use crate::read;
|
use crate::ValueReader;
|
||||||
use crate::read_iovalue;
|
|
||||||
|
|
||||||
pub fn from_bytes<'de, D: Domain, Dec: DomainDecode<D>>(
|
pub fn from_bytes<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||||
bs: &'de [u8],
|
bs: &'de [u8],
|
||||||
decode_embedded: &mut Dec,
|
decode_embedded: &mut Dec,
|
||||||
) -> io::Result<ShellHandle<'de, D>> {
|
) -> io::Result<ShellHandle<'de, D>> {
|
||||||
read(&mut BytesBinarySource::new(bs).packed(), false, decode_embedded)
|
Ok(Shell::read(&mut BytesBinarySource::new(bs).packed(), false, decode_embedded)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
|
pub fn annotated_from_bytes<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||||
super::BytesBinarySource::new(bs).packed().next_iovalue(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn annotated_from_bytes<'de, D: Domain, Dec: DomainDecode<D>>(
|
|
||||||
bs: &'de [u8],
|
bs: &'de [u8],
|
||||||
decode_embedded: &mut Dec,
|
decode_embedded: &mut Dec,
|
||||||
) -> io::Result<ShellHandle<'de, D>> {
|
) -> io::Result<ShellHandle<'de, D>> {
|
||||||
read(&mut super::BytesBinarySource::new(bs).packed(), true, decode_embedded)
|
Ok(Shell::read(&mut BytesBinarySource::new(bs).packed(), true, decode_embedded)?)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
|
|
||||||
read_iovalue(&mut super::BytesBinarySource::new(bs).packed(), true)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use crate::{ValueClass, AtomClass, Atom};
|
use crate::ValueClass;
|
||||||
use crate::error::{self, ExpectedKind};
|
use crate::AtomClass;
|
||||||
|
use crate::Atom;
|
||||||
|
use crate::error::ExpectedKind;
|
||||||
|
use crate::error;
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::cast::{FromPrimitive, ToPrimitive};
|
use num_traits::cast::{FromPrimitive, ToPrimitive};
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
use std::borrow::Borrow;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::hash::Hasher;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
@ -11,7 +14,6 @@ use crate::BinarySource;
|
||||||
use crate::BytesBinarySource;
|
use crate::BytesBinarySource;
|
||||||
use crate::Domain;
|
use crate::Domain;
|
||||||
use crate::DomainDecode;
|
use crate::DomainDecode;
|
||||||
use crate::IOValue;
|
|
||||||
use crate::NoEmbeddedDomainCodec;
|
use crate::NoEmbeddedDomainCodec;
|
||||||
use crate::PackedWriter;
|
use crate::PackedWriter;
|
||||||
use crate::SignedInteger;
|
use crate::SignedInteger;
|
||||||
|
@ -20,6 +22,7 @@ use crate::ValueImpl;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::error::io_eof;
|
use crate::error::io_eof;
|
||||||
use crate::reader::NextToken;
|
use crate::reader::NextToken;
|
||||||
|
use crate::value_eq;
|
||||||
|
|
||||||
use super::constants::Tag;
|
use super::constants::Tag;
|
||||||
|
|
||||||
|
@ -29,24 +32,28 @@ struct Index<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct IndexedRepr<'de, Packed: AsRef<[u8]> + 'de, D> {
|
struct IndexedRepr<'de, D> {
|
||||||
packed: Packed,
|
packed: Cow<'de, [u8]>,
|
||||||
index: Index<D>,
|
index: Index<D>,
|
||||||
phantom: PhantomData<&'de ()>,
|
phantom: PhantomData<&'de ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct View<'de, Packed: AsRef<[u8]> + 'de, D: Domain> {
|
pub struct View<'de, D: Domain> {
|
||||||
repr: Arc<IndexedRepr<'de, Packed, D>>,
|
repr: Arc<IndexedRepr<'de, D>>,
|
||||||
annotation_offset: usize,
|
annotation_offset: usize,
|
||||||
value_range: Range<usize>,
|
value_range: Range<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct IOView<'de>(IOViewImpl<'de>);
|
||||||
|
pub type IOViewImpl<'de> = View<'de, IOView<'de>>;
|
||||||
|
|
||||||
struct IndexInProgress<'dec, D, Dec> {
|
struct IndexInProgress<'dec, D, Dec> {
|
||||||
embedded: Vec<(Range<usize>, D)>,
|
embedded: Vec<(Range<usize>, D)>,
|
||||||
dec: &'dec mut Dec,
|
dec: &'dec mut Dec,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Indexer<'de, 'dec, D: Domain, Dec: DomainDecode<D>> {
|
struct Indexer<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> {
|
||||||
packed: &'de [u8],
|
packed: &'de [u8],
|
||||||
offset: usize,
|
offset: usize,
|
||||||
index: Option<IndexInProgress<'dec, D, Dec>>,
|
index: Option<IndexInProgress<'dec, D, Dec>>,
|
||||||
|
@ -79,7 +86,7 @@ fn varint(packed: &[u8], mut i: usize) -> io::Result<(u64, usize)> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'dec, D: Domain, Dec: DomainDecode<D>> Indexer<'de, 'dec, D, Dec> {
|
impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> Indexer<'de, 'dec, D, Dec> {
|
||||||
fn skip_annotations(&mut self) -> io::Result<()> {
|
fn skip_annotations(&mut self) -> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
if tag_at(&self.packed, self.offset)? == Tag::Annotation {
|
if tag_at(&self.packed, self.offset)? == Tag::Annotation {
|
||||||
|
@ -160,10 +167,10 @@ impl<'de, 'dec, D: Domain, Dec: DomainDecode<D>> Indexer<'de, 'dec, D, Dec> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> IndexedRepr<'de, Packed, D> {
|
impl<'de, D: Domain> IndexedRepr<'de, D> {
|
||||||
fn trim(&self, range: Range<usize>) -> Arc<IndexedRepr<'static, Box<[u8]>, D>> {
|
fn trim(&self, range: Range<usize>) -> Arc<IndexedRepr<'static, D>> {
|
||||||
Arc::new(IndexedRepr {
|
Arc::new(IndexedRepr {
|
||||||
packed: self.packed.as_ref()[range.clone()].to_vec().into_boxed_slice(),
|
packed: self.packed.as_ref()[range.clone()].to_vec().into(),
|
||||||
index: Index {
|
index: Index {
|
||||||
embedded: match self.index.embedded.as_ref() {
|
embedded: match self.index.embedded.as_ref() {
|
||||||
Some(e) => {
|
Some(e) => {
|
||||||
|
@ -183,12 +190,12 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> IndexedRepr<'de, Packed, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> View<'de, Packed, D> {
|
impl<'de, D: Domain> View<'de, D> {
|
||||||
pub fn new<Dec: DomainDecode<D>>(packed: Packed, dec: Option<&mut Dec>) -> io::Result<Self> {
|
pub fn new<Dec: DomainDecode<'de, D>>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>) -> io::Result<Self> {
|
||||||
Self::new_offset(packed, dec, 0)
|
Self::new_offset(packed, dec, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trim(&self) -> View<'static, Box<[u8]>, D> {
|
pub fn trim(&self) -> View<'static, D> {
|
||||||
View {
|
View {
|
||||||
repr: self.repr.trim(self.annotation_offset .. self.value_range.end),
|
repr: self.repr.trim(self.annotation_offset .. self.value_range.end),
|
||||||
annotation_offset: 0,
|
annotation_offset: 0,
|
||||||
|
@ -197,7 +204,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> View<'de, Packed, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_offset<Dec: DomainDecode<D>>(packed: Packed, dec: Option<&mut Dec>, offset: usize) -> io::Result<Self> {
|
pub fn new_offset<Dec: DomainDecode<'de, D>>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>, offset: usize) -> io::Result<Self> {
|
||||||
let mut indexer = Indexer {
|
let mut indexer = Indexer {
|
||||||
packed: packed.as_ref(),
|
packed: packed.as_ref(),
|
||||||
offset,
|
offset,
|
||||||
|
@ -224,7 +231,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> View<'de, Packed, D> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner_new(repr: &Arc<IndexedRepr<'de, Packed, D>>, offset: usize) -> io::Result<Self> {
|
fn inner_new(repr: &Arc<IndexedRepr<'de, D>>, offset: usize) -> io::Result<Self> {
|
||||||
let mut indexer: Indexer<D, NoEmbeddedDomainCodec> = Indexer {
|
let mut indexer: Indexer<D, NoEmbeddedDomainCodec> = Indexer {
|
||||||
packed: repr.packed.as_ref(),
|
packed: repr.packed.as_ref(),
|
||||||
offset,
|
offset,
|
||||||
|
@ -292,7 +299,12 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> View<'de, Packed, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Clone for View<'de, Packed, D> {
|
impl<'de, D: Domain> Domain for View<'de, D> {
|
||||||
|
type Decode = NoEmbeddedDomainCodec;
|
||||||
|
type Encode = NoEmbeddedDomainCodec;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, D: Domain> Clone for View<'de, D> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
View {
|
View {
|
||||||
repr: self.repr.clone(),
|
repr: self.repr.clone(),
|
||||||
|
@ -302,12 +314,13 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Clone for View<'de, Packed, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packed, D> {
|
impl<'de, D: Domain> ValueImpl for View<'de, D> {
|
||||||
type Handle = Self;
|
type Handle = Self;
|
||||||
type Embedded = D;
|
type Embedded = D;
|
||||||
type Mapped<E: Domain> = View<'de, Packed, E>;
|
type Mapped<E: Domain> = View<'de, E>;
|
||||||
type Items<'a> = ViewIterator<IndexedRepr<'de, Packed, D>> where Self: 'a;
|
type Items<'a> = ViewIterator<IndexedRepr<'de, D>> where Self: 'a;
|
||||||
type Entries<'a> = DictionaryAdapter<IndexedRepr<'de, Packed, D>> where Self: 'a;
|
type Entries<'a> = DictionaryAdapter<IndexedRepr<'de, D>> where Self: 'a;
|
||||||
|
type IOEmbedded = IOView<'de>;
|
||||||
|
|
||||||
fn wrap(self) -> Self::Handle {
|
fn wrap(self) -> Self::Handle {
|
||||||
self
|
self
|
||||||
|
@ -442,7 +455,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packed,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has<E: ValueImpl<Embedded = Self::Embedded>>(&self, v: &E::Handle) -> bool {
|
fn has<E: ValueImpl<Embedded = Self::Embedded>>(&self, v: &E::Handle) -> bool {
|
||||||
self.iter().find(|e| v == &**e).is_some()
|
self.iter().find(|e| value_eq(v.borrow(), e)).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_dictionary(&self) -> bool {
|
fn is_dictionary(&self) -> bool {
|
||||||
|
@ -451,7 +464,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packed,
|
||||||
|
|
||||||
fn get<K: ValueImpl<Embedded = Self::Embedded>>(&self, k: &K::Handle) -> Option<Self::Handle> {
|
fn get<K: ValueImpl<Embedded = Self::Embedded>>(&self, k: &K::Handle) -> Option<Self::Handle> {
|
||||||
for (kk, vv) in self.entries() {
|
for (kk, vv) in self.entries() {
|
||||||
if &*kk == k { return Some(vv); }
|
if value_eq(k.borrow(), &kk) { return Some(vv); }
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -479,17 +492,17 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> {
|
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>> {
|
||||||
if self.value_range.start == self.annotation_offset {
|
if self.value_range.start == self.annotation_offset {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let repr = Arc::new(IndexedRepr {
|
let repr = Arc::new(IndexedRepr {
|
||||||
packed: self.repr.packed.as_ref(),
|
packed: self.repr.packed.as_ref().into(),
|
||||||
index: Index::<IOValue> { embedded: None },
|
index: Index::<IOView> { embedded: None },
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
});
|
});
|
||||||
let anns: Vec<IOValue> = AnnotationAdapter(ViewIterator::inner_new(&repr, self.annotation_offset))
|
let anns: Vec<IOViewImpl> =
|
||||||
.collect();
|
AnnotationAdapter(ViewIterator::inner_new(&repr, self.annotation_offset)).collect();
|
||||||
Some(Cow::Owned(anns))
|
Some(Cow::Owned(anns))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -515,17 +528,78 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ValueImpl for View<'de, Packed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::impl_value_methods!({'de, Packed: AsRef<[u8]> + 'de, D: Domain}, View<'de, Packed, D>);
|
crate::impl_value_methods!({'de, D: Domain}, View<'de, D>);
|
||||||
|
|
||||||
pub struct ViewStream<'de, 'dec, D: Domain, Dec: DomainDecode<D> = <D as Domain>::Decode> {
|
impl<'de> Clone for IOView<'de> {
|
||||||
buf: &'de [u8],
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Debug for IOView<'de> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.0.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Ord for IOView<'de> {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.0.cmp(&other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Hash for IOView<'de> {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.0.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> PartialOrd for IOView<'de> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
self.0.partial_cmp(&other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> PartialEq for IOView<'de> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.0 == other.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Eq for IOView<'de> {}
|
||||||
|
|
||||||
|
impl<'de> Domain for IOView<'de> {
|
||||||
|
type Decode = NoEmbeddedDomainCodec;
|
||||||
|
type Encode = NoEmbeddedDomainCodec;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> From<IOViewImpl<'de>> for IOView<'de> {
|
||||||
|
fn from(v: IOViewImpl<'de>) -> Self {
|
||||||
|
IOView(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Into<IOViewImpl<'de>> for IOView<'de> {
|
||||||
|
fn into(self) -> IOViewImpl<'de> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> AsRef<IOViewImpl<'de>> for IOView<'de> {
|
||||||
|
fn as_ref(&self) -> &IOViewImpl<'de> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ViewStream<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D> = <D as Domain>::Decode> {
|
||||||
|
buf: Cow<'de, [u8]>,
|
||||||
dec: Option<&'dec mut Dec>,
|
dec: Option<&'dec mut Dec>,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
phantom: PhantomData<&'de D>,
|
phantom: PhantomData<&'de D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'dec, D: Domain, Dec: DomainDecode<D>> ViewStream<'de, 'dec, D, Dec> {
|
impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> ViewStream<'de, 'dec, D, Dec> {
|
||||||
pub fn new(buf: &'de [u8], dec: Option<&'dec mut Dec>) -> Self {
|
pub fn new(buf: Cow<'de, [u8]>, dec: Option<&'dec mut Dec>) -> Self {
|
||||||
ViewStream {
|
ViewStream {
|
||||||
buf,
|
buf,
|
||||||
dec,
|
dec,
|
||||||
|
@ -535,8 +609,8 @@ impl<'de, 'dec, D: Domain, Dec: DomainDecode<D>> ViewStream<'de, 'dec, D, Dec> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'dec, D: Domain, Dec: DomainDecode<D>> Iterator for ViewStream<'de, 'dec, D, Dec> {
|
impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> Iterator for ViewStream<'de, 'dec, D, Dec> {
|
||||||
type Item = io::Result<View<'de, &'de [u8], D>>;
|
type Item = io::Result<View<'de, D>>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.offset >= self.buf.len() {
|
if self.offset >= self.buf.len() {
|
||||||
|
@ -558,14 +632,14 @@ pub struct ViewIterator<Repr> {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ViewIterator<IndexedRepr<'de, Packed, D>> {
|
impl<'de, D: Domain> ViewIterator<IndexedRepr<'de, D>> {
|
||||||
pub fn inner_new(repr: &Arc<IndexedRepr<'de, Packed, D>>, offset: usize) -> Self {
|
pub fn inner_new(repr: &Arc<IndexedRepr<'de, D>>, offset: usize) -> Self {
|
||||||
ViewIterator { repr: Arc::clone(repr), offset }
|
ViewIterator { repr: Arc::clone(repr), offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for ViewIterator<IndexedRepr<'de, Packed, D>> {
|
impl<'de, D: Domain> Iterator for ViewIterator<IndexedRepr<'de, D>> {
|
||||||
type Item = View<'de, Packed, D>;
|
type Item = View<'de, D>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Ok(Tag::End) = tag_at(self.repr.packed.as_ref(), self.offset) {
|
if let Ok(Tag::End) = tag_at(self.repr.packed.as_ref(), self.offset) {
|
||||||
|
@ -580,8 +654,8 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for ViewIterator<Indexe
|
||||||
|
|
||||||
pub struct DictionaryAdapter<Repr>(pub ViewIterator<Repr>);
|
pub struct DictionaryAdapter<Repr>(pub ViewIterator<Repr>);
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for DictionaryAdapter<IndexedRepr<'de, Packed, D>> {
|
impl<'de, D: Domain> Iterator for DictionaryAdapter<IndexedRepr<'de, D>> {
|
||||||
type Item = (View<'de, Packed, D>, View<'de, Packed, D>);
|
type Item = (View<'de, D>, View<'de, D>);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let k = self.0.next()?;
|
let k = self.0.next()?;
|
||||||
|
@ -592,8 +666,8 @@ impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for DictionaryAdapter<I
|
||||||
|
|
||||||
pub struct AnnotationAdapter<Repr>(pub ViewIterator<Repr>);
|
pub struct AnnotationAdapter<Repr>(pub ViewIterator<Repr>);
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for AnnotationAdapter<IndexedRepr<'de, Packed, D>> {
|
impl<'de> Iterator for AnnotationAdapter<IndexedRepr<'de, IOView<'de>>> {
|
||||||
type Item = View<'de, Packed, D>;
|
type Item = IOViewImpl<'de>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Ok(Tag::Annotation) = tag_at(self.0.repr.packed.as_ref(), self.0.offset) {
|
if let Ok(Tag::Annotation) = tag_at(self.0.repr.packed.as_ref(), self.0.offset) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::convert::TryInto;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use super::constants::Tag;
|
use super::constants::Tag;
|
||||||
use crate::{boundary as B, ValueImpl, DomainEncode, IOValue, IOValueDomainCodec, Writer};
|
use crate::{boundary as B, ValueImpl, DomainEncode, Writer};
|
||||||
|
|
||||||
struct Buffers<W: io::Write> {
|
struct Buffers<W: io::Write> {
|
||||||
base: W,
|
base: W,
|
||||||
|
@ -44,11 +44,6 @@ impl PackedWriter<&mut Vec<u8>> {
|
||||||
v.write(&mut PackedWriter::new(&mut buf), enc)?;
|
v.write(&mut PackedWriter::new(&mut buf), enc)?;
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn encode_iovalue(v: &IOValue) -> io::Result<Vec<u8>> {
|
|
||||||
Self::encode(&mut IOValueDomainCodec, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {
|
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {
|
||||||
|
|
|
@ -1,28 +1,16 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
|
use crate::Atom;
|
||||||
use crate::BinarySource;
|
use crate::BinarySource;
|
||||||
use crate::CompoundClass;
|
use crate::CompoundClass;
|
||||||
use crate::Shell;
|
|
||||||
use crate::ShellHandle;
|
|
||||||
use crate::SignedInteger;
|
use crate::SignedInteger;
|
||||||
use crate::ValueClass;
|
use crate::ValueClass;
|
||||||
use crate::ValueImpl;
|
|
||||||
use crate::boundary as B;
|
use crate::boundary as B;
|
||||||
use crate::domain::Domain;
|
|
||||||
use crate::domain::DomainDecode;
|
|
||||||
use crate::domain::IOValueDomainCodec;
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::error::ExpectedKind;
|
use crate::error::ExpectedKind;
|
||||||
use crate::error::io_eof;
|
use crate::error::io_eof;
|
||||||
use crate::repr::Annotations;
|
|
||||||
use crate::repr::Atom;
|
|
||||||
use crate::repr::IOValue;
|
|
||||||
use crate::repr::Map;
|
|
||||||
use crate::repr::Record;
|
|
||||||
use crate::repr::Set;
|
|
||||||
|
|
||||||
pub type ReaderResult<T> = std::result::Result<T, Error>;
|
pub type ReaderResult<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
@ -178,126 +166,3 @@ pub trait Reader<'de> {
|
||||||
|
|
||||||
fn specialized(&mut self) -> Option<(&str, &mut dyn BinarySource<'de>)> { None }
|
fn specialized(&mut self) -> Option<(&str, &mut dyn BinarySource<'de>)> { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gather_annotations<'de, R: Reader<'de> + ?Sized>(
|
|
||||||
r: &mut R,
|
|
||||||
) -> io::Result<Option<(Vec<IOValue>, ValueClass)>> {
|
|
||||||
let mut anns = Vec::new();
|
|
||||||
loop {
|
|
||||||
match r.peek_class()? {
|
|
||||||
None => return Ok(None),
|
|
||||||
Some(NextToken::Value(v)) => return Ok(Some((anns, v))),
|
|
||||||
Some(NextToken::Annotation) => {
|
|
||||||
r.open_annotation()?;
|
|
||||||
anns.push(read_iovalue(r, true)?);
|
|
||||||
r.close_annotation()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read<'produced, 'de, R: Reader<'de> + ?Sized, D: Domain, Dec: DomainDecode<D>>(
|
|
||||||
r: &mut R,
|
|
||||||
read_annotations: bool,
|
|
||||||
dec: &mut Dec,
|
|
||||||
) -> io::Result<ShellHandle<'produced, D>> {
|
|
||||||
let (anns, v) = match read_annotations {
|
|
||||||
true => gather_annotations(r)?.ok_or_else(io_eof)?,
|
|
||||||
false => (Vec::new(), r.skip_annotations()?.ok_or_else(io_eof)?),
|
|
||||||
};
|
|
||||||
let value = match v {
|
|
||||||
ValueClass::Atomic(_) =>
|
|
||||||
Shell::Atom(r.next_atom()?),
|
|
||||||
ValueClass::Embedded => {
|
|
||||||
r.open_embedded()?;
|
|
||||||
let v = dec.decode_embedded(r, read_annotations)?;
|
|
||||||
r.close_embedded()?;
|
|
||||||
Shell::Embedded(v)
|
|
||||||
}
|
|
||||||
ValueClass::Compound(CompoundClass::Record) => {
|
|
||||||
let mut vs = Vec::new();
|
|
||||||
r.open_record()?;
|
|
||||||
let mut b = B::start(B::Item::RecordLabel);
|
|
||||||
r.boundary(&b)?;
|
|
||||||
vs.push(read(r, read_annotations, dec)?);
|
|
||||||
while !r.close_compound(&mut b, &B::Item::RecordField)? {
|
|
||||||
vs.push(read(r, read_annotations, dec)?);
|
|
||||||
}
|
|
||||||
Shell::Record(Record::_from_vec(vs))
|
|
||||||
}
|
|
||||||
ValueClass::Compound(CompoundClass::Sequence) => {
|
|
||||||
let mut vs = Vec::new();
|
|
||||||
r.open_sequence()?;
|
|
||||||
let mut b = B::Type::default();
|
|
||||||
while !r.close_compound(&mut b, &B::Item::SequenceValue)? {
|
|
||||||
vs.push(read(r, read_annotations, dec)?);
|
|
||||||
}
|
|
||||||
Shell::Sequence(vs)
|
|
||||||
}
|
|
||||||
ValueClass::Compound(CompoundClass::Set) => {
|
|
||||||
let mut s = Set::new();
|
|
||||||
r.open_set()?;
|
|
||||||
let mut b = B::Type::default();
|
|
||||||
while !r.close_compound(&mut b, &B::Item::SetValue)? {
|
|
||||||
s.insert(read(r, read_annotations, dec)?);
|
|
||||||
}
|
|
||||||
Shell::Set(s)
|
|
||||||
}
|
|
||||||
ValueClass::Compound(CompoundClass::Dictionary) => {
|
|
||||||
let mut d = Map::new();
|
|
||||||
r.open_dictionary()?;
|
|
||||||
let mut b = B::Type::default();
|
|
||||||
while !r.close_compound(&mut b, &B::Item::DictionaryKey)? {
|
|
||||||
let k = read(r, read_annotations, dec)?;
|
|
||||||
b.shift(Some(B::Item::DictionaryValue));
|
|
||||||
r.boundary(&b)?;
|
|
||||||
d.insert(k, read(r, read_annotations, dec)?);
|
|
||||||
}
|
|
||||||
Shell::Dictionary(d)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if anns.is_empty() {
|
|
||||||
Ok(value.wrap())
|
|
||||||
} else {
|
|
||||||
Ok(Shell::Annotated(Annotations::new(value.wrap(), anns)).wrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
|
|
||||||
r: &mut R,
|
|
||||||
read_annotations: bool,
|
|
||||||
) -> io::Result<IOValue> {
|
|
||||||
Ok(read(r, read_annotations, &mut IOValueDomainCodec)?.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IOValues<'de, R: Reader<'de>> {
|
|
||||||
pub reader: R,
|
|
||||||
pub read_annotations: bool,
|
|
||||||
phantom: PhantomData<&'de ()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, R: Reader<'de>> IOValues<'de, R> {
|
|
||||||
pub fn new(reader: R) -> Self {
|
|
||||||
IOValues {
|
|
||||||
reader,
|
|
||||||
read_annotations: false,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_annotations(mut self, read_annotations: bool) -> Self {
|
|
||||||
self.read_annotations = read_annotations;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, R: Reader<'de>> std::iter::Iterator for IOValues<'de, R> {
|
|
||||||
type Item = io::Result<IOValue>;
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
match self.reader.peek_class() {
|
|
||||||
Err(e) => Some(Err(e)),
|
|
||||||
Ok(None) => None,
|
|
||||||
Ok(Some(_)) => Some(read_iovalue(&mut self.reader, self.read_annotations)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ use std::hash::Hash;
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use crate::DomainDecode;
|
||||||
|
use crate::Reader;
|
||||||
|
use crate::error::ReadError;
|
||||||
|
use crate::reader::NextToken;
|
||||||
use crate::signed_integer::OutOfRange;
|
use crate::signed_integer::OutOfRange;
|
||||||
use crate::AtomClass;
|
use crate::AtomClass;
|
||||||
use crate::CompoundClass;
|
use crate::CompoundClass;
|
||||||
|
@ -19,6 +23,46 @@ use crate::write_value;
|
||||||
|
|
||||||
use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64};
|
use super::float::{eq_f32, eq_f64, cmp_f32, cmp_f64};
|
||||||
|
|
||||||
|
pub trait ValueReader {
|
||||||
|
type Impl<'de>: ValueImpl;
|
||||||
|
|
||||||
|
fn read_impl<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<<Self::Impl<'de> as ValueImpl>::Embedded>>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
dec: &mut Dec,
|
||||||
|
) -> Result<Self::Impl<'de>, ReadError>;
|
||||||
|
|
||||||
|
fn read<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<<Self::Impl<'de> as ValueImpl>::Embedded>>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
dec: &mut Dec,
|
||||||
|
) -> Result<<Self::Impl<'de> as ValueImpl>::Handle, ReadError> {
|
||||||
|
Ok(Self::read_impl(r, read_annotations, dec)?.wrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
) -> Result<<Self::Impl<'de> as ValueImpl>::IOEmbedded, ReadError>;
|
||||||
|
|
||||||
|
fn gather_annotations<'de, R: Reader<'de> + ?Sized>(
|
||||||
|
r: &mut R,
|
||||||
|
) -> io::Result<Option<(Vec<<<Self::Impl<'de> as ValueImpl>::Mapped<<Self::Impl<'de> as ValueImpl>::IOEmbedded> as ValueImpl>::Handle>, ValueClass)>> {
|
||||||
|
let mut anns = Vec::new();
|
||||||
|
loop {
|
||||||
|
match r.peek_class()? {
|
||||||
|
None => return Ok(None),
|
||||||
|
Some(NextToken::Value(v)) => return Ok(Some((anns, v))),
|
||||||
|
Some(NextToken::Annotation) => {
|
||||||
|
r.open_annotation()?;
|
||||||
|
anns.push(Self::read_iovalue(r, true)?.into());
|
||||||
|
r.close_annotation()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Atomic values from the specification.
|
/// Atomic values from the specification.
|
||||||
pub trait ValueImpl: Sized {
|
pub trait ValueImpl: Sized {
|
||||||
type Handle: Borrow<Self> + Clone + From<Self> + Hash + Eq + Ord + PartialEq + PartialOrd;
|
type Handle: Borrow<Self> + Clone + From<Self> + Hash + Eq + Ord + PartialEq + PartialOrd;
|
||||||
|
@ -26,7 +70,11 @@ pub trait ValueImpl: Sized {
|
||||||
type Mapped<E: Domain>: ValueImpl<Embedded = E>;
|
type Mapped<E: Domain>: ValueImpl<Embedded = E>;
|
||||||
type Items<'a>: Iterator<Item = Self::Handle> + 'a where Self: 'a;
|
type Items<'a>: Iterator<Item = Self::Handle> + 'a where Self: 'a;
|
||||||
type Entries<'a>: Iterator<Item = (Self::Handle, Self::Handle)> + 'a where Self: 'a;
|
type Entries<'a>: Iterator<Item = (Self::Handle, Self::Handle)> + 'a where Self: 'a;
|
||||||
type IOValueImpl: ValueImpl<Embedded = <Self::IOValueImpl as ValueImpl>::Handle>;
|
|
||||||
|
type IOEmbedded: From<<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle> +
|
||||||
|
Into<<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle> +
|
||||||
|
AsRef<<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle> +
|
||||||
|
Domain;
|
||||||
|
|
||||||
fn wrap(self) -> Self::Handle;
|
fn wrap(self) -> Self::Handle;
|
||||||
|
|
||||||
|
@ -75,7 +123,7 @@ pub trait ValueImpl: Sized {
|
||||||
fn as_embedded(&self) -> Option<Cow<'_, Self::Embedded>>;
|
fn as_embedded(&self) -> Option<Cow<'_, Self::Embedded>>;
|
||||||
|
|
||||||
// INVARIANT: return Some() *only* when the contained collection is nonempty
|
// INVARIANT: return Some() *only* when the contained collection is nonempty
|
||||||
fn annotations(&self) -> Option<Cow<'_, [<Self::IOValueImpl as ValueImpl>::Handle]>>;
|
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>>;
|
||||||
|
|
||||||
fn peeled(v: &Self::Handle) -> Self::Handle;
|
fn peeled(v: &Self::Handle) -> Self::Handle;
|
||||||
|
|
||||||
|
@ -219,13 +267,13 @@ pub fn value_cmp<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(v: &V, w: &
|
||||||
|| iters_cmp::<V, W>(&v.iter(), &w.iter())),
|
|| iters_cmp::<V, W>(&v.iter(), &w.iter())),
|
||||||
CompoundClass::Sequence => iters_cmp::<V, W>(&v.iter(), &w.iter()),
|
CompoundClass::Sequence => iters_cmp::<V, W>(&v.iter(), &w.iter()),
|
||||||
CompoundClass::Set => {
|
CompoundClass::Set => {
|
||||||
let s1 = v.iter().collect::<Set<_>>();
|
let s1 = v.iter().collect::<BTreeSet<_>>();
|
||||||
let s2 = w.iter().collect::<Set<_>>();
|
let s2 = w.iter().collect::<BTreeSet<_>>();
|
||||||
todo!() // s1.cmp(&s2)
|
todo!() // s1.cmp(&s2)
|
||||||
}
|
}
|
||||||
CompoundClass::Dictionary => {
|
CompoundClass::Dictionary => {
|
||||||
let d1 = v.entries().collect::<Map<_, _>>();
|
let d1 = v.entries().collect::<BTreeMap<_, _>>();
|
||||||
let d2 = w.entries().collect::<Map<_, _>>();
|
let d2 = w.entries().collect::<BTreeMap<_, _>>();
|
||||||
todo!() // d1.cmp(&d2)
|
todo!() // d1.cmp(&d2)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,15 +13,21 @@ use bytemuck::TransparentWrapper;
|
||||||
use crate::AtomClass;
|
use crate::AtomClass;
|
||||||
use crate::CompoundClass;
|
use crate::CompoundClass;
|
||||||
use crate::Domain;
|
use crate::Domain;
|
||||||
|
use crate::DomainDecode;
|
||||||
use crate::DomainEncode;
|
use crate::DomainEncode;
|
||||||
use crate::ExpectedKind;
|
use crate::ExpectedKind;
|
||||||
use crate::IOValueDomainCodec;
|
use crate::IOValueDomainDecode;
|
||||||
|
use crate::IOValueDomainEncode;
|
||||||
|
use crate::Reader;
|
||||||
use crate::SignedInteger;
|
use crate::SignedInteger;
|
||||||
use crate::ValueClass;
|
use crate::ValueClass;
|
||||||
use crate::ValueImpl;
|
use crate::ValueImpl;
|
||||||
use crate::Writer;
|
use crate::Writer;
|
||||||
use crate::boundary as B;
|
use crate::boundary as B;
|
||||||
|
use crate::error::ReadError;
|
||||||
|
use crate::error::io_eof;
|
||||||
use crate::impl_value_methods;
|
use crate::impl_value_methods;
|
||||||
|
use crate::repr::ValueReader;
|
||||||
|
|
||||||
pub use std::collections::BTreeSet as Set;
|
pub use std::collections::BTreeSet as Set;
|
||||||
pub use std::collections::BTreeMap as Map;
|
pub use std::collections::BTreeMap as Map;
|
||||||
|
@ -38,6 +44,18 @@ pub enum Atom<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Atom<'a> {
|
impl<'a> Atom<'a> {
|
||||||
|
pub fn into_owned(self) -> Atom<'static> {
|
||||||
|
match self {
|
||||||
|
Atom::Boolean(b) => Atom::Boolean(b),
|
||||||
|
Atom::Float(f) => Atom::Float(f),
|
||||||
|
Atom::Double(d) => Atom::Double(d),
|
||||||
|
Atom::SignedInteger(i) => Atom::SignedInteger(i.to_owned()),
|
||||||
|
Atom::String(s) => Atom::String(s.to_owned()),
|
||||||
|
Atom::ByteString(bs) => Atom::ByteString(bs.to_owned()),
|
||||||
|
Atom::Symbol(s) => Atom::Symbol(s.to_owned()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(&self, w: &mut dyn Writer) -> io::Result<()> {
|
pub fn write(&self, w: &mut dyn Writer) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Atom::Boolean(b) => w.write_bool(*b),
|
Atom::Boolean(b) => w.write_bool(*b),
|
||||||
|
@ -158,13 +176,35 @@ impl<'a, D: Domain> Shell<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<D: Domain> ValueReader for Shell<'_, D> {
|
||||||
|
type Impl<'de> = Shell<'de, D>;
|
||||||
|
|
||||||
|
fn read_impl<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, <Self::Impl<'de> as ValueImpl>::Embedded>>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
dec: &mut Dec,
|
||||||
|
) -> Result<Self::Impl<'de>, ReadError> {
|
||||||
|
Ok(read(r, read_annotations, dec)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
) -> Result<<Self::Impl<'de> as ValueImpl>::IOEmbedded, ReadError> {
|
||||||
|
Ok(Shell::<'de, IOValue>::read_impl(
|
||||||
|
r,
|
||||||
|
read_annotations,
|
||||||
|
&mut IOValueDomainDecode::<Shell<'de, IOValue>>::default())?.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
||||||
type Handle = ShellHandle<'a, D>;
|
type Handle = ShellHandle<'a, D>;
|
||||||
type Embedded = D;
|
type Embedded = D;
|
||||||
type Mapped<E: Domain> = Shell<'a, E>;
|
type Mapped<E: Domain> = Shell<'a, E>;
|
||||||
type Items<'i> = std::slice::Iter<'i, Self::Handle> where Self: 'i;
|
type Items<'i> = std::slice::Iter<'i, Self::Handle> where Self: 'i;
|
||||||
type Entries<'i> = std::collections::btree_map::Iter<'i, Self::Handle, Self::Handle> where Self: 'i;
|
type Entries<'i> = std::collections::btree_map::Iter<'i, Self::Handle, Self::Handle> where Self: 'i;
|
||||||
type IOValueImpl = IOValue;
|
type IOEmbedded = IOValue<'a>;
|
||||||
|
|
||||||
fn wrap(self) -> Self::Handle {
|
fn wrap(self) -> Self::Handle {
|
||||||
Self::Handle::new(self)
|
Self::Handle::new(self)
|
||||||
|
@ -225,7 +265,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
||||||
for ann in anns {
|
for ann in anns {
|
||||||
b.shift(Some(B::Item::Annotation));
|
b.shift(Some(B::Item::Annotation));
|
||||||
w.boundary(&b)?;
|
w.boundary(&b)?;
|
||||||
ann.value().write(w, &mut IOValueDomainCodec)?;
|
ann.write(w, &mut IOValueDomainEncode::<Self>::default())?;
|
||||||
}
|
}
|
||||||
b.shift(Some(B::Item::AnnotatedValue));
|
b.shift(Some(B::Item::AnnotatedValue));
|
||||||
w.boundary(&b)?;
|
w.boundary(&b)?;
|
||||||
|
@ -284,7 +324,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
||||||
if let Some(anns) = w.annotations() {
|
if let Some(anns) = w.annotations() {
|
||||||
Ok(Shell::Annotated(Annotations(Box::new((
|
Ok(Shell::Annotated(Annotations(Box::new((
|
||||||
r,
|
r,
|
||||||
anns.iter().map(copy_iovalue::<E::IOValueImpl>).collect()
|
anns.iter().map(copy_iovalue::<E>).map(|a| a.into()).collect()
|
||||||
)))).wrap())
|
)))).wrap())
|
||||||
} else {
|
} else {
|
||||||
Ok(r)
|
Ok(r)
|
||||||
|
@ -426,7 +466,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn annotations(&self) -> Option<Cow<'_, [<Self::IOValueImpl as ValueImpl>::Handle]>> {
|
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>> {
|
||||||
match self {
|
match self {
|
||||||
Shell::Annotated(b) => Some(Cow::Borrowed(&b.0.as_ref().1)),
|
Shell::Annotated(b) => Some(Cow::Borrowed(&b.0.as_ref().1)),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -494,10 +534,10 @@ impl<V> Record<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Annotations<V: ValueImpl>(Box<(V::Handle, Vec<<V::IOValueImpl as ValueImpl>::Handle>)>);
|
pub struct Annotations<V: ValueImpl>(Box<(V::Handle, Vec<<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle>)>);
|
||||||
|
|
||||||
impl<V: ValueImpl> Annotations<V> {
|
impl<V: ValueImpl> Annotations<V> {
|
||||||
pub fn new(v: V::Handle, anns: Vec<<V::IOValueImpl as ValueImpl>::Handle>) -> Self {
|
pub fn new(v: V::Handle, anns: Vec<<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle>) -> Self {
|
||||||
Self(Box::new((v, anns)))
|
Self(Box::new((v, anns)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,47 +568,54 @@ impl<V: ValueImpl> PartialOrd for Annotations<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_iovalue<V: ValueImpl<Embedded = <V as ValueImpl>::Handle>>(v: &V::Handle) -> IOValue {
|
pub fn copy_iovalue<V: ValueImpl>(v: &<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle) -> IOValue {
|
||||||
IOValue::copy::<V, _, _>(v, &mut |a| Result::<_, ()>::Ok(copy_iovalue::<V>(a))).unwrap()
|
Shell::copy::<V::Mapped<V::IOEmbedded>, _, _>(v, &mut |a| Result::<_, ()>::Ok(
|
||||||
|
copy_iovalue::<V>(a.as_ref()).into())).unwrap().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type IOValueImpl = Shell<'static, IOValue>;
|
pub type IOValueImpl<'a> = Shell<'a, IOValue<'a>>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct IOValue(ShellHandle<'static, IOValue>);
|
pub struct IOValue<'a>(ShellHandle<'a, IOValue<'a>>);
|
||||||
unsafe impl TransparentWrapper<ShellHandle<'static, IOValue>> for IOValue {}
|
unsafe impl<'a> TransparentWrapper<ShellHandle<'a, IOValue<'a>>> for IOValue<'a> {}
|
||||||
|
|
||||||
impl Domain for IOValue {
|
impl Domain for IOValue<'_> {
|
||||||
type Decode = IOValueDomainCodec;
|
type Decode = IOValueDomainDecode<Self>;
|
||||||
type Encode = IOValueDomainCodec;
|
type Encode = IOValueDomainEncode<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for IOValue {
|
impl<'a> Debug for IOValue<'a> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
IOValue::peel_ref(self).fmt(f)
|
IOValue::peel_ref(self).fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IOValue {
|
impl<'a> IOValue<'a> {
|
||||||
pub fn value(&self) -> &IOValueImpl {
|
pub fn value(&self) -> &IOValueImpl<'a> {
|
||||||
self.0.as_ref()
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<IOValueImpl>> From<T> for IOValue {
|
impl<'a, T: Into<IOValueImpl<'a>>> From<T> for IOValue<'a> {
|
||||||
fn from(t: T) -> Self {
|
fn from(t: T) -> Self {
|
||||||
IOValue(t.into().wrap())
|
IOValue(t.into().wrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Borrow<IOValueImpl> for IOValue {
|
impl<'a> Borrow<IOValueImpl<'a>> for IOValue<'a> {
|
||||||
fn borrow(&self) -> &IOValueImpl {
|
fn borrow(&self) -> &IOValueImpl<'a> {
|
||||||
self.0.as_ref()
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for IOValue {
|
impl<'a> AsRef<Arc<Shell<'a, IOValue<'a>>>> for IOValue<'a> {
|
||||||
|
fn as_ref(&self) -> &Arc<Shell<'a, IOValue<'a>>> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FromStr for IOValue<'a> {
|
||||||
type Err = io::Error;
|
type Err = io::Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
@ -576,37 +623,56 @@ impl FromStr for IOValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<<IOValueImpl as ValueImpl>::Handle> for IOValue {
|
impl<'a> From<<IOValueImpl<'a> as ValueImpl>::Handle> for IOValue<'a> {
|
||||||
fn from(h: <IOValueImpl as ValueImpl>::Handle) -> Self {
|
fn from(h: <IOValueImpl<'a> as ValueImpl>::Handle) -> Self {
|
||||||
TransparentWrapper::wrap(h)
|
TransparentWrapper::wrap(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a <IOValueImpl as ValueImpl>::Handle> for &'a IOValue {
|
impl<'r, 'a> From<&'r <IOValueImpl<'a> as ValueImpl>::Handle> for &'r IOValue<'a> {
|
||||||
fn from(h: &'a <IOValueImpl as ValueImpl>::Handle) -> Self {
|
fn from(h: &'r <IOValueImpl<'a> as ValueImpl>::Handle) -> Self {
|
||||||
TransparentWrapper::wrap_ref(h)
|
TransparentWrapper::wrap_ref(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IOValue> for <IOValueImpl as ValueImpl>::Handle {
|
impl<'a> From<IOValue<'a>> for <IOValueImpl<'a> as ValueImpl>::Handle {
|
||||||
fn from(i: IOValue) -> Self {
|
fn from(i: IOValue<'a>) -> Self {
|
||||||
IOValue::peel(i)
|
IOValue::peel(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a IOValue> for &'a <IOValueImpl as ValueImpl>::Handle {
|
impl<'r, 'a> From<&'r IOValue<'a>> for &'r <IOValueImpl<'a> as ValueImpl>::Handle {
|
||||||
fn from(i: &'a IOValue) -> Self {
|
fn from(i: &'r IOValue<'a>) -> Self {
|
||||||
IOValue::peel_ref(i)
|
IOValue::peel_ref(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueImpl for IOValue {
|
impl<'a> ValueReader for IOValue<'a> {
|
||||||
type Handle = IOValue;
|
type Impl<'i> = IOValue<'i>;
|
||||||
type Embedded = IOValue;
|
|
||||||
type Mapped<E: Domain> = Shell<'static, E>;
|
fn read_impl<'de, R: Reader<'de> + ?Sized, Dec: DomainDecode<'de, <Self::Impl<'de> as ValueImpl>::Embedded>>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
dec: &mut Dec,
|
||||||
|
) -> Result<Self::Impl<'de>, ReadError> {
|
||||||
|
Ok(read(r, read_annotations, dec)?.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_iovalue<'de, R: Reader<'de> + ?Sized>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
) -> Result<<Self::Impl<'de> as ValueImpl>::IOEmbedded, ReadError> {
|
||||||
|
Self::read(r, read_annotations, &mut IOValueDomainDecode::<Self>::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ValueImpl for IOValue<'a> {
|
||||||
|
type Handle = Self;
|
||||||
|
type Embedded = Self;
|
||||||
|
type Mapped<E: Domain> = Shell<'a, E>;
|
||||||
type Items<'i> = std::slice::Iter<'i, Self::Handle> where Self: 'i;
|
type Items<'i> = std::slice::Iter<'i, Self::Handle> where Self: 'i;
|
||||||
type Entries<'i> = std::collections::btree_map::Iter<'i, Self::Handle, Self::Handle> where Self: 'i;
|
type Entries<'i> = std::collections::btree_map::Iter<'i, Self::Handle, Self::Handle> where Self: 'i;
|
||||||
type IOValueImpl = IOValue;
|
type IOEmbedded = Self;
|
||||||
|
|
||||||
fn wrap(self) -> Self::Handle {
|
fn wrap(self) -> Self::Handle {
|
||||||
self
|
self
|
||||||
|
@ -692,7 +758,7 @@ impl ValueImpl for IOValue {
|
||||||
self.value().as_embedded()
|
self.value().as_embedded()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> {
|
fn annotations(&self) -> Option<Cow<'_, [<Self::Mapped<Self::IOEmbedded> as ValueImpl>::Handle]>> {
|
||||||
self.value().annotations()
|
self.value().annotations()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,3 +778,70 @@ impl ValueImpl for IOValue {
|
||||||
IOValueImpl::map_embedded(v.into(), f)
|
IOValueImpl::map_embedded(v.into(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read<'de, R: Reader<'de> + ?Sized, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||||
|
r: &mut R,
|
||||||
|
read_annotations: bool,
|
||||||
|
dec: &mut Dec,
|
||||||
|
) -> io::Result<Shell<'de, D>> {
|
||||||
|
let (anns, v) = match read_annotations {
|
||||||
|
true => IOValue::gather_annotations(r)?.ok_or_else(io_eof)?,
|
||||||
|
false => (Vec::new(), r.skip_annotations()?.ok_or_else(io_eof)?),
|
||||||
|
};
|
||||||
|
let value = match v {
|
||||||
|
ValueClass::Atomic(_) =>
|
||||||
|
Shell::Atom(r.next_atom()?),
|
||||||
|
ValueClass::Embedded => {
|
||||||
|
r.open_embedded()?;
|
||||||
|
let v = dec.decode_embedded(r, read_annotations)?;
|
||||||
|
r.close_embedded()?;
|
||||||
|
Shell::Embedded(v)
|
||||||
|
}
|
||||||
|
ValueClass::Compound(CompoundClass::Record) => {
|
||||||
|
let mut vs = Vec::new();
|
||||||
|
r.open_record()?;
|
||||||
|
let mut b = B::start(B::Item::RecordLabel);
|
||||||
|
r.boundary(&b)?;
|
||||||
|
vs.push(read(r, read_annotations, dec)?.wrap());
|
||||||
|
while !r.close_compound(&mut b, &B::Item::RecordField)? {
|
||||||
|
vs.push(read(r, read_annotations, dec)?.wrap());
|
||||||
|
}
|
||||||
|
Shell::Record(Record::_from_vec(vs))
|
||||||
|
}
|
||||||
|
ValueClass::Compound(CompoundClass::Sequence) => {
|
||||||
|
let mut vs = Vec::new();
|
||||||
|
r.open_sequence()?;
|
||||||
|
let mut b = B::Type::default();
|
||||||
|
while !r.close_compound(&mut b, &B::Item::SequenceValue)? {
|
||||||
|
vs.push(read(r, read_annotations, dec)?.wrap());
|
||||||
|
}
|
||||||
|
Shell::Sequence(vs)
|
||||||
|
}
|
||||||
|
ValueClass::Compound(CompoundClass::Set) => {
|
||||||
|
let mut s = Set::new();
|
||||||
|
r.open_set()?;
|
||||||
|
let mut b = B::Type::default();
|
||||||
|
while !r.close_compound(&mut b, &B::Item::SetValue)? {
|
||||||
|
s.insert(read(r, read_annotations, dec)?.wrap());
|
||||||
|
}
|
||||||
|
Shell::Set(s)
|
||||||
|
}
|
||||||
|
ValueClass::Compound(CompoundClass::Dictionary) => {
|
||||||
|
let mut d = Map::new();
|
||||||
|
r.open_dictionary()?;
|
||||||
|
let mut b = B::Type::default();
|
||||||
|
while !r.close_compound(&mut b, &B::Item::DictionaryKey)? {
|
||||||
|
let k = read(r, read_annotations, dec)?.wrap();
|
||||||
|
b.shift(Some(B::Item::DictionaryValue));
|
||||||
|
r.boundary(&b)?;
|
||||||
|
d.insert(k, read(r, read_annotations, dec)?.wrap());
|
||||||
|
}
|
||||||
|
Shell::Dictionary(d)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if anns.is_empty() {
|
||||||
|
Ok(value)
|
||||||
|
} else {
|
||||||
|
Ok(Shell::Annotated(Annotations::new(value.wrap(), anns)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,30 +10,22 @@ use crate::BinarySource;
|
||||||
use crate::BytesBinarySource;
|
use crate::BytesBinarySource;
|
||||||
use crate::Domain;
|
use crate::Domain;
|
||||||
use crate::DomainDecode;
|
use crate::DomainDecode;
|
||||||
use crate::IOValue;
|
use crate::Shell;
|
||||||
use crate::PlainValue;
|
use crate::ShellHandle;
|
||||||
use crate::Reader;
|
use crate::ValueReader;
|
||||||
|
|
||||||
pub fn from_str<'de, D: Domain, Dec: DomainDecode<D>>(
|
pub fn from_str<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||||
s: &'de str,
|
s: &'de str,
|
||||||
decode_embedded: &mut Dec,
|
decode_embedded: &mut Dec,
|
||||||
) -> io::Result<PlainValue<'de, D>> {
|
) -> io::Result<ShellHandle<'de, D>> {
|
||||||
BytesBinarySource::new(s.as_bytes()).text().next(false, decode_embedded)
|
Ok(Shell::read(&mut BytesBinarySource::new(s.as_bytes()).text(), false, decode_embedded)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
|
pub fn annotated_from_str<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||||
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn annotated_from_str<'de, D: Domain, Dec: DomainDecode<D>>(
|
|
||||||
s: &'de str,
|
s: &'de str,
|
||||||
decode_embedded: &mut Dec,
|
decode_embedded: &mut Dec,
|
||||||
) -> io::Result<PlainValue<'de, D>> {
|
) -> io::Result<ShellHandle<'de, D>> {
|
||||||
BytesBinarySource::new(s.as_bytes()).text().next(true, decode_embedded)
|
Ok(Shell::read(&mut BytesBinarySource::new(s.as_bytes()).text(), true, decode_embedded)?)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
|
|
||||||
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -266,9 +266,9 @@ impl<'de, S: BinarySource<'de>> TextReader<'de, S>
|
||||||
return match NUMBER_RE.captures(&s) {
|
return match NUMBER_RE.captures(&s) {
|
||||||
None => Ok(Atom::Symbol(s.into())),
|
None => Ok(Atom::Symbol(s.into())),
|
||||||
Some(m) => match m.get(2) {
|
Some(m) => match m.get(2) {
|
||||||
None => Ok(Atom::SignedInteger(s.parse::<BigInt>().map_err(
|
None => Ok(Atom::SignedInteger(Cow::Owned(s.parse::<BigInt>().map_err(
|
||||||
|_| self.syntax_error(&format!(
|
|_| self.syntax_error(&format!(
|
||||||
"Invalid signed-integer number: {:?}", s)))?.into())),
|
"Invalid signed-integer number: {:?}", s)))?.into()))),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
if let Some(maybe_f) = m.get(7) {
|
if let Some(maybe_f) = m.get(7) {
|
||||||
let s = m[1].to_owned() + &m[3];
|
let s = m[1].to_owned() + &m[3];
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use crate::DomainEncode;
|
use crate::DomainEncode;
|
||||||
use crate::IOValue;
|
|
||||||
use crate::IOValueDomainCodec;
|
|
||||||
use crate::ValueImpl;
|
use crate::ValueImpl;
|
||||||
use crate::Writer;
|
use crate::Writer;
|
||||||
use crate::hex::HexFormatter;
|
use crate::hex::HexFormatter;
|
||||||
|
@ -56,10 +54,6 @@ impl TextWriter<&mut Vec<u8>> {
|
||||||
v.write(&mut TextWriter::new(&mut buf), enc)?;
|
v.write(&mut TextWriter::new(&mut buf), enc)?;
|
||||||
Ok(String::from_utf8(buf).expect("valid UTF-8 from TextWriter"))
|
Ok(String::from_utf8(buf).expect("valid UTF-8 from TextWriter"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode_iovalue(v: &IOValue) -> io::Result<String> {
|
|
||||||
Self::encode(&mut IOValueDomainCodec, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: io::Write> TextWriter<W> {
|
impl<W: io::Write> TextWriter<W> {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::io;
|
||||||
use crate::AtomClass;
|
use crate::AtomClass;
|
||||||
use crate::CompoundClass;
|
use crate::CompoundClass;
|
||||||
use crate::DomainEncode;
|
use crate::DomainEncode;
|
||||||
use crate::IOValueDomainCodec;
|
use crate::IOValueDomainEncode;
|
||||||
use crate::SignedInteger;
|
use crate::SignedInteger;
|
||||||
use crate::ValueClass;
|
use crate::ValueClass;
|
||||||
use crate::boundary as B;
|
use crate::boundary as B;
|
||||||
|
@ -86,7 +86,7 @@ pub fn write_value<V: ValueImpl>(
|
||||||
for ann in &anns[..] {
|
for ann in &anns[..] {
|
||||||
annotation_b.shift(Some(B::Item::Annotation));
|
annotation_b.shift(Some(B::Item::Annotation));
|
||||||
w.boundary(&annotation_b)?;
|
w.boundary(&annotation_b)?;
|
||||||
ann.borrow().write(w, &mut IOValueDomainCodec)?;
|
ann.borrow().write(w, &mut IOValueDomainEncode::<V>::default())?;
|
||||||
}
|
}
|
||||||
annotation_b.shift(Some(B::Item::AnnotatedValue));
|
annotation_b.shift(Some(B::Item::AnnotatedValue));
|
||||||
w.boundary(&annotation_b)?;
|
w.boundary(&annotation_b)?;
|
||||||
|
|
Loading…
Reference in New Issue