More boulder-pushing
This commit is contained in:
parent
4070c5252d
commit
025c5bb962
|
@ -1,17 +1,15 @@
|
|||
use std::io;
|
||||
|
||||
use super::IOValue;
|
||||
use super::Reader;
|
||||
use super::Writer;
|
||||
use super::ValueImpl;
|
||||
|
||||
pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone + 'static {
|
||||
type Decode: DomainDecode<Self> + Default;
|
||||
pub trait Domain: std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone {
|
||||
type Decode: for<'de> DomainDecode<'de, Self> + Default;
|
||||
type Encode: DomainEncode<Self> + Default;
|
||||
}
|
||||
|
||||
pub trait DomainDecode<D: Domain> {
|
||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
||||
pub trait DomainDecode<'de, D: Domain> {
|
||||
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||
&mut self,
|
||||
r: &mut R,
|
||||
read_annotations: bool,
|
||||
|
@ -26,8 +24,8 @@ pub trait DomainEncode<D: Domain> {
|
|||
) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl<'a, D: Domain, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
|
||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
||||
impl<'a, 'de, D: Domain, T: DomainDecode<'de, D>> DomainDecode<'de, D> for &'a mut T {
|
||||
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||
&mut self,
|
||||
r: &mut R,
|
||||
read_annotations: bool,
|
||||
|
@ -49,8 +47,8 @@ impl<'a, D: Domain, T: DomainEncode<D>> DomainEncode<D> for &'a mut T {
|
|||
#[derive(Default)]
|
||||
pub struct DefaultDomainCodec;
|
||||
|
||||
impl<D: Domain> DomainDecode<D> for DefaultDomainCodec {
|
||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
||||
impl<'de, D: Domain> DomainDecode<'de, D> for DefaultDomainCodec {
|
||||
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||
&mut self,
|
||||
r: &mut R,
|
||||
read_annotations: bool,
|
||||
|
@ -72,8 +70,8 @@ impl<D: Domain> DomainEncode<D> for DefaultDomainCodec {
|
|||
#[derive(Default)]
|
||||
pub struct DebugDomainCodec;
|
||||
|
||||
impl<Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<D> for DebugDomainCodec {
|
||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
||||
impl<'de, Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<'de, D> for DebugDomainCodec {
|
||||
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||
&mut self,
|
||||
r: &mut R,
|
||||
_read_annotations: bool,
|
||||
|
@ -95,8 +93,8 @@ impl<D: Domain> DomainEncode<D> for DebugDomainCodec {
|
|||
#[derive(Default)]
|
||||
pub struct NoEmbeddedDomainCodec;
|
||||
|
||||
impl<D: Domain> DomainDecode<D> for NoEmbeddedDomainCodec {
|
||||
fn decode_embedded<'de, R: Reader<'de> + ?Sized>(
|
||||
impl<'de, D: Domain> DomainDecode<'de, D> for NoEmbeddedDomainCodec {
|
||||
fn decode_embedded<R: Reader<'de> + ?Sized>(
|
||||
&mut self,
|
||||
_r: &mut R,
|
||||
_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"))
|
||||
}
|
||||
}
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ReadError {
|
||||
UnsupportedFormat,
|
||||
Io(io::Error),
|
||||
}
|
||||
|
||||
impl From<ExpectedKind> for Error {
|
||||
fn from(e: ExpectedKind) -> Self {
|
||||
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 {
|
||||
fn from(e: Error) -> Self {
|
||||
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::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 {
|
||||
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 float;
|
||||
pub mod hex;
|
||||
pub mod iovalue;
|
||||
pub mod merge;
|
||||
pub mod packed;
|
||||
pub mod reader;
|
||||
|
@ -10,26 +11,25 @@ pub mod repr;
|
|||
pub mod shell;
|
||||
pub mod signed_integer;
|
||||
pub mod source;
|
||||
// pub mod text;
|
||||
pub mod text;
|
||||
pub mod types;
|
||||
pub mod writer;
|
||||
|
||||
pub use domain::*;
|
||||
pub use error::Error;
|
||||
pub use error::ExpectedKind;
|
||||
pub use iovalue::IOValueDomainDecode;
|
||||
pub use iovalue::IOValueDomainEncode;
|
||||
pub use iovalue::IOValues;
|
||||
pub use merge::merge;
|
||||
pub use merge::merge2;
|
||||
pub use packed::PackedReader;
|
||||
pub use packed::PackedWriter;
|
||||
pub use packed::annotated_from_bytes;
|
||||
pub use packed::annotated_iovalue_from_bytes;
|
||||
pub use packed::from_bytes;
|
||||
pub use packed::iovalue_from_bytes;
|
||||
pub use reader::IOValues;
|
||||
pub use reader::Reader;
|
||||
pub use reader::read;
|
||||
pub use reader::read_iovalue;
|
||||
pub use repr::ValueImpl;
|
||||
pub use repr::ValueReader;
|
||||
pub use repr::value_eq;
|
||||
pub use repr::value_cmp;
|
||||
pub use repr::value_hash;
|
||||
|
@ -45,12 +45,10 @@ pub use signed_integer::SignedInteger;
|
|||
pub use source::BinarySource;
|
||||
pub use source::BytesBinarySource;
|
||||
pub use source::IOBinarySource;
|
||||
// pub use text::TextReader;
|
||||
// pub use text::TextWriter;
|
||||
// pub use text::annotated_from_str;
|
||||
// pub use text::annotated_iovalue_from_str;
|
||||
// pub use text::from_str;
|
||||
// pub use text::iovalue_from_str;
|
||||
pub use text::TextReader;
|
||||
pub use text::TextWriter;
|
||||
pub use text::annotated_from_str;
|
||||
pub use text::from_str;
|
||||
pub use types::AtomClass;
|
||||
pub use types::CompoundClass;
|
||||
pub use types::ValueClass;
|
||||
|
|
|
@ -12,29 +12,20 @@ use crate::BinarySource;
|
|||
use crate::BytesBinarySource;
|
||||
use crate::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::IOValue;
|
||||
use crate::Shell;
|
||||
use crate::ShellHandle;
|
||||
use crate::read;
|
||||
use crate::read_iovalue;
|
||||
use crate::ValueReader;
|
||||
|
||||
pub fn from_bytes<'de, D: Domain, Dec: DomainDecode<D>>(
|
||||
pub fn from_bytes<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||
bs: &'de [u8],
|
||||
decode_embedded: &mut Dec,
|
||||
) -> 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> {
|
||||
super::BytesBinarySource::new(bs).packed().next_iovalue(false)
|
||||
}
|
||||
|
||||
pub fn annotated_from_bytes<'de, D: Domain, Dec: DomainDecode<D>>(
|
||||
pub fn annotated_from_bytes<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||
bs: &'de [u8],
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<ShellHandle<'de, D>> {
|
||||
read(&mut super::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)
|
||||
Ok(Shell::read(&mut BytesBinarySource::new(bs).packed(), true, decode_embedded)?)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{ValueClass, AtomClass, Atom};
|
||||
use crate::error::{self, ExpectedKind};
|
||||
use crate::ValueClass;
|
||||
use crate::AtomClass;
|
||||
use crate::Atom;
|
||||
use crate::error::ExpectedKind;
|
||||
use crate::error;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::cast::{FromPrimitive, ToPrimitive};
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::hash::Hasher;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Range;
|
||||
|
@ -11,7 +14,6 @@ use crate::BinarySource;
|
|||
use crate::BytesBinarySource;
|
||||
use crate::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::IOValue;
|
||||
use crate::NoEmbeddedDomainCodec;
|
||||
use crate::PackedWriter;
|
||||
use crate::SignedInteger;
|
||||
|
@ -20,6 +22,7 @@ use crate::ValueImpl;
|
|||
use crate::error;
|
||||
use crate::error::io_eof;
|
||||
use crate::reader::NextToken;
|
||||
use crate::value_eq;
|
||||
|
||||
use super::constants::Tag;
|
||||
|
||||
|
@ -29,24 +32,28 @@ struct Index<D> {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct IndexedRepr<'de, Packed: AsRef<[u8]> + 'de, D> {
|
||||
packed: Packed,
|
||||
struct IndexedRepr<'de, D> {
|
||||
packed: Cow<'de, [u8]>,
|
||||
index: Index<D>,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
||||
pub struct View<'de, Packed: AsRef<[u8]> + 'de, D: Domain> {
|
||||
repr: Arc<IndexedRepr<'de, Packed, D>>,
|
||||
pub struct View<'de, D: Domain> {
|
||||
repr: Arc<IndexedRepr<'de, D>>,
|
||||
annotation_offset: 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> {
|
||||
embedded: Vec<(Range<usize>, D)>,
|
||||
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],
|
||||
offset: usize,
|
||||
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<()> {
|
||||
loop {
|
||||
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> {
|
||||
fn trim(&self, range: Range<usize>) -> Arc<IndexedRepr<'static, Box<[u8]>, D>> {
|
||||
impl<'de, D: Domain> IndexedRepr<'de, D> {
|
||||
fn trim(&self, range: Range<usize>) -> Arc<IndexedRepr<'static, D>> {
|
||||
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 {
|
||||
embedded: match self.index.embedded.as_ref() {
|
||||
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> {
|
||||
pub fn new<Dec: DomainDecode<D>>(packed: Packed, dec: Option<&mut Dec>) -> io::Result<Self> {
|
||||
impl<'de, D: Domain> View<'de, D> {
|
||||
pub fn new<Dec: DomainDecode<'de, D>>(packed: Cow<'de, [u8]>, dec: Option<&mut Dec>) -> io::Result<Self> {
|
||||
Self::new_offset(packed, dec, 0)
|
||||
}
|
||||
|
||||
pub fn trim(&self) -> View<'static, Box<[u8]>, D> {
|
||||
pub fn trim(&self) -> View<'static, D> {
|
||||
View {
|
||||
repr: self.repr.trim(self.annotation_offset .. self.value_range.end),
|
||||
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 {
|
||||
packed: packed.as_ref(),
|
||||
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 {
|
||||
packed: repr.packed.as_ref(),
|
||||
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 {
|
||||
View {
|
||||
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 Embedded = D;
|
||||
type Mapped<E: Domain> = View<'de, Packed, E>;
|
||||
type Items<'a> = ViewIterator<IndexedRepr<'de, Packed, D>> where Self: 'a;
|
||||
type Entries<'a> = DictionaryAdapter<IndexedRepr<'de, Packed, D>> where Self: 'a;
|
||||
type Mapped<E: Domain> = View<'de, E>;
|
||||
type Items<'a> = ViewIterator<IndexedRepr<'de, D>> where Self: 'a;
|
||||
type Entries<'a> = DictionaryAdapter<IndexedRepr<'de, D>> where Self: 'a;
|
||||
type IOEmbedded = IOView<'de>;
|
||||
|
||||
fn wrap(self) -> Self::Handle {
|
||||
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 {
|
||||
self.iter().find(|e| v == &**e).is_some()
|
||||
self.iter().find(|e| value_eq(v.borrow(), e)).is_some()
|
||||
}
|
||||
|
||||
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> {
|
||||
for (kk, vv) in self.entries() {
|
||||
if &*kk == k { return Some(vv); }
|
||||
if value_eq(k.borrow(), &kk) { return Some(vv); }
|
||||
}
|
||||
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 {
|
||||
None
|
||||
} else {
|
||||
let repr = Arc::new(IndexedRepr {
|
||||
packed: self.repr.packed.as_ref(),
|
||||
index: Index::<IOValue> { embedded: None },
|
||||
packed: self.repr.packed.as_ref().into(),
|
||||
index: Index::<IOView> { embedded: None },
|
||||
phantom: PhantomData,
|
||||
});
|
||||
let anns: Vec<IOValue> = AnnotationAdapter(ViewIterator::inner_new(&repr, self.annotation_offset))
|
||||
.collect();
|
||||
let anns: Vec<IOViewImpl> =
|
||||
AnnotationAdapter(ViewIterator::inner_new(&repr, self.annotation_offset)).collect();
|
||||
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> {
|
||||
buf: &'de [u8],
|
||||
impl<'de> Clone for IOView<'de> {
|
||||
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>,
|
||||
offset: usize,
|
||||
phantom: PhantomData<&'de D>,
|
||||
}
|
||||
|
||||
impl<'de, 'dec, D: Domain, Dec: DomainDecode<D>> ViewStream<'de, 'dec, D, Dec> {
|
||||
pub fn new(buf: &'de [u8], dec: Option<&'dec mut Dec>) -> Self {
|
||||
impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> ViewStream<'de, 'dec, D, Dec> {
|
||||
pub fn new(buf: Cow<'de, [u8]>, dec: Option<&'dec mut Dec>) -> Self {
|
||||
ViewStream {
|
||||
buf,
|
||||
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> {
|
||||
type Item = io::Result<View<'de, &'de [u8], D>>;
|
||||
impl<'de, 'dec, D: Domain, Dec: DomainDecode<'de, D>> Iterator for ViewStream<'de, 'dec, D, Dec> {
|
||||
type Item = io::Result<View<'de, D>>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.offset >= self.buf.len() {
|
||||
|
@ -558,14 +632,14 @@ pub struct ViewIterator<Repr> {
|
|||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> ViewIterator<IndexedRepr<'de, Packed, D>> {
|
||||
pub fn inner_new(repr: &Arc<IndexedRepr<'de, Packed, D>>, offset: usize) -> Self {
|
||||
impl<'de, D: Domain> ViewIterator<IndexedRepr<'de, D>> {
|
||||
pub fn inner_new(repr: &Arc<IndexedRepr<'de, D>>, offset: usize) -> Self {
|
||||
ViewIterator { repr: Arc::clone(repr), offset }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for ViewIterator<IndexedRepr<'de, Packed, D>> {
|
||||
type Item = View<'de, Packed, D>;
|
||||
impl<'de, D: Domain> Iterator for ViewIterator<IndexedRepr<'de, D>> {
|
||||
type Item = View<'de, D>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
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>);
|
||||
|
||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for DictionaryAdapter<IndexedRepr<'de, Packed, D>> {
|
||||
type Item = (View<'de, Packed, D>, View<'de, Packed, D>);
|
||||
impl<'de, D: Domain> Iterator for DictionaryAdapter<IndexedRepr<'de, D>> {
|
||||
type Item = (View<'de, D>, View<'de, D>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
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>);
|
||||
|
||||
impl<'de, Packed: AsRef<[u8]> + 'de, D: Domain> Iterator for AnnotationAdapter<IndexedRepr<'de, Packed, D>> {
|
||||
type Item = View<'de, Packed, D>;
|
||||
impl<'de> Iterator for AnnotationAdapter<IndexedRepr<'de, IOView<'de>>> {
|
||||
type Item = IOViewImpl<'de>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
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::Write;
|
||||
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> {
|
||||
base: W,
|
||||
|
@ -44,11 +44,6 @@ impl PackedWriter<&mut Vec<u8>> {
|
|||
v.write(&mut PackedWriter::new(&mut buf), enc)?;
|
||||
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> {
|
||||
|
|
|
@ -1,28 +1,16 @@
|
|||
use std::borrow::Cow;
|
||||
use std::convert::TryFrom;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::Atom;
|
||||
use crate::BinarySource;
|
||||
use crate::CompoundClass;
|
||||
use crate::Shell;
|
||||
use crate::ShellHandle;
|
||||
use crate::SignedInteger;
|
||||
use crate::ValueClass;
|
||||
use crate::ValueImpl;
|
||||
use crate::boundary as B;
|
||||
use crate::domain::Domain;
|
||||
use crate::domain::DomainDecode;
|
||||
use crate::domain::IOValueDomainCodec;
|
||||
use crate::error::Error;
|
||||
use crate::error::ExpectedKind;
|
||||
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>;
|
||||
|
||||
|
@ -178,126 +166,3 @@ pub trait Reader<'de> {
|
|||
|
||||
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::io;
|
||||
|
||||
use crate::DomainDecode;
|
||||
use crate::Reader;
|
||||
use crate::error::ReadError;
|
||||
use crate::reader::NextToken;
|
||||
use crate::signed_integer::OutOfRange;
|
||||
use crate::AtomClass;
|
||||
use crate::CompoundClass;
|
||||
|
@ -19,6 +23,46 @@ use crate::write_value;
|
|||
|
||||
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.
|
||||
pub trait ValueImpl: Sized {
|
||||
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 Items<'a>: Iterator<Item = 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;
|
||||
|
||||
|
@ -75,7 +123,7 @@ pub trait ValueImpl: Sized {
|
|||
fn as_embedded(&self) -> Option<Cow<'_, Self::Embedded>>;
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -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())),
|
||||
CompoundClass::Sequence => iters_cmp::<V, W>(&v.iter(), &w.iter()),
|
||||
CompoundClass::Set => {
|
||||
let s1 = v.iter().collect::<Set<_>>();
|
||||
let s2 = w.iter().collect::<Set<_>>();
|
||||
let s1 = v.iter().collect::<BTreeSet<_>>();
|
||||
let s2 = w.iter().collect::<BTreeSet<_>>();
|
||||
todo!() // s1.cmp(&s2)
|
||||
}
|
||||
CompoundClass::Dictionary => {
|
||||
let d1 = v.entries().collect::<Map<_, _>>();
|
||||
let d2 = w.entries().collect::<Map<_, _>>();
|
||||
let d1 = v.entries().collect::<BTreeMap<_, _>>();
|
||||
let d2 = w.entries().collect::<BTreeMap<_, _>>();
|
||||
todo!() // d1.cmp(&d2)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -13,15 +13,21 @@ use bytemuck::TransparentWrapper;
|
|||
use crate::AtomClass;
|
||||
use crate::CompoundClass;
|
||||
use crate::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::DomainEncode;
|
||||
use crate::ExpectedKind;
|
||||
use crate::IOValueDomainCodec;
|
||||
use crate::IOValueDomainDecode;
|
||||
use crate::IOValueDomainEncode;
|
||||
use crate::Reader;
|
||||
use crate::SignedInteger;
|
||||
use crate::ValueClass;
|
||||
use crate::ValueImpl;
|
||||
use crate::Writer;
|
||||
use crate::boundary as B;
|
||||
use crate::error::ReadError;
|
||||
use crate::error::io_eof;
|
||||
use crate::impl_value_methods;
|
||||
use crate::repr::ValueReader;
|
||||
|
||||
pub use std::collections::BTreeSet as Set;
|
||||
pub use std::collections::BTreeMap as Map;
|
||||
|
@ -38,6 +44,18 @@ pub enum 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<()> {
|
||||
match self {
|
||||
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> {
|
||||
type Handle = ShellHandle<'a, D>;
|
||||
type Embedded = D;
|
||||
type Mapped<E: Domain> = Shell<'a, E>;
|
||||
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 IOValueImpl = IOValue;
|
||||
type IOEmbedded = IOValue<'a>;
|
||||
|
||||
fn wrap(self) -> Self::Handle {
|
||||
Self::Handle::new(self)
|
||||
|
@ -225,7 +265,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
|||
for ann in anns {
|
||||
b.shift(Some(B::Item::Annotation));
|
||||
w.boundary(&b)?;
|
||||
ann.value().write(w, &mut IOValueDomainCodec)?;
|
||||
ann.write(w, &mut IOValueDomainEncode::<Self>::default())?;
|
||||
}
|
||||
b.shift(Some(B::Item::AnnotatedValue));
|
||||
w.boundary(&b)?;
|
||||
|
@ -284,7 +324,7 @@ impl<'a, D: Domain> ValueImpl for Shell<'a, D> {
|
|||
if let Some(anns) = w.annotations() {
|
||||
Ok(Shell::Annotated(Annotations(Box::new((
|
||||
r,
|
||||
anns.iter().map(copy_iovalue::<E::IOValueImpl>).collect()
|
||||
anns.iter().map(copy_iovalue::<E>).map(|a| a.into()).collect()
|
||||
)))).wrap())
|
||||
} else {
|
||||
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 {
|
||||
Shell::Annotated(b) => Some(Cow::Borrowed(&b.0.as_ref().1)),
|
||||
_ => None,
|
||||
|
@ -494,10 +534,10 @@ impl<V> Record<V> {
|
|||
}
|
||||
|
||||
#[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> {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
IOValue::copy::<V, _, _>(v, &mut |a| Result::<_, ()>::Ok(copy_iovalue::<V>(a))).unwrap()
|
||||
pub fn copy_iovalue<V: ValueImpl>(v: &<V::Mapped<V::IOEmbedded> as ValueImpl>::Handle) -> IOValue {
|
||||
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)]
|
||||
#[repr(transparent)]
|
||||
pub struct IOValue(ShellHandle<'static, IOValue>);
|
||||
unsafe impl TransparentWrapper<ShellHandle<'static, IOValue>> for IOValue {}
|
||||
pub struct IOValue<'a>(ShellHandle<'a, IOValue<'a>>);
|
||||
unsafe impl<'a> TransparentWrapper<ShellHandle<'a, IOValue<'a>>> for IOValue<'a> {}
|
||||
|
||||
impl Domain for IOValue {
|
||||
type Decode = IOValueDomainCodec;
|
||||
type Encode = IOValueDomainCodec;
|
||||
impl Domain for IOValue<'_> {
|
||||
type Decode = IOValueDomainDecode<Self>;
|
||||
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 {
|
||||
IOValue::peel_ref(self).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl IOValue {
|
||||
pub fn value(&self) -> &IOValueImpl {
|
||||
impl<'a> IOValue<'a> {
|
||||
pub fn value(&self) -> &IOValueImpl<'a> {
|
||||
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 {
|
||||
IOValue(t.into().wrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<IOValueImpl> for IOValue {
|
||||
fn borrow(&self) -> &IOValueImpl {
|
||||
impl<'a> Borrow<IOValueImpl<'a>> for IOValue<'a> {
|
||||
fn borrow(&self) -> &IOValueImpl<'a> {
|
||||
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;
|
||||
|
||||
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 {
|
||||
fn from(h: <IOValueImpl as ValueImpl>::Handle) -> Self {
|
||||
impl<'a> From<<IOValueImpl<'a> as ValueImpl>::Handle> for IOValue<'a> {
|
||||
fn from(h: <IOValueImpl<'a> as ValueImpl>::Handle) -> Self {
|
||||
TransparentWrapper::wrap(h)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a <IOValueImpl as ValueImpl>::Handle> for &'a IOValue {
|
||||
fn from(h: &'a <IOValueImpl as ValueImpl>::Handle) -> Self {
|
||||
impl<'r, 'a> From<&'r <IOValueImpl<'a> as ValueImpl>::Handle> for &'r IOValue<'a> {
|
||||
fn from(h: &'r <IOValueImpl<'a> as ValueImpl>::Handle) -> Self {
|
||||
TransparentWrapper::wrap_ref(h)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IOValue> for <IOValueImpl as ValueImpl>::Handle {
|
||||
fn from(i: IOValue) -> Self {
|
||||
impl<'a> From<IOValue<'a>> for <IOValueImpl<'a> as ValueImpl>::Handle {
|
||||
fn from(i: IOValue<'a>) -> Self {
|
||||
IOValue::peel(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a IOValue> for &'a <IOValueImpl as ValueImpl>::Handle {
|
||||
fn from(i: &'a IOValue) -> Self {
|
||||
impl<'r, 'a> From<&'r IOValue<'a>> for &'r <IOValueImpl<'a> as ValueImpl>::Handle {
|
||||
fn from(i: &'r IOValue<'a>) -> Self {
|
||||
IOValue::peel_ref(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueImpl for IOValue {
|
||||
type Handle = IOValue;
|
||||
type Embedded = IOValue;
|
||||
type Mapped<E: Domain> = Shell<'static, E>;
|
||||
impl<'a> ValueReader for IOValue<'a> {
|
||||
type Impl<'i> = IOValue<'i>;
|
||||
|
||||
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 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 {
|
||||
self
|
||||
|
@ -692,7 +758,7 @@ impl ValueImpl for IOValue {
|
|||
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()
|
||||
}
|
||||
|
||||
|
@ -712,3 +778,70 @@ impl ValueImpl for IOValue {
|
|||
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::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::IOValue;
|
||||
use crate::PlainValue;
|
||||
use crate::Reader;
|
||||
use crate::Shell;
|
||||
use crate::ShellHandle;
|
||||
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,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<PlainValue<'de, D>> {
|
||||
BytesBinarySource::new(s.as_bytes()).text().next(false, decode_embedded)
|
||||
) -> io::Result<ShellHandle<'de, D>> {
|
||||
Ok(Shell::read(&mut BytesBinarySource::new(s.as_bytes()).text(), false, decode_embedded)?)
|
||||
}
|
||||
|
||||
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
|
||||
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(false)
|
||||
}
|
||||
|
||||
pub fn annotated_from_str<'de, D: Domain, Dec: DomainDecode<D>>(
|
||||
pub fn annotated_from_str<'de, D: Domain, Dec: DomainDecode<'de, D>>(
|
||||
s: &'de str,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<PlainValue<'de, D>> {
|
||||
BytesBinarySource::new(s.as_bytes()).text().next(true, decode_embedded)
|
||||
}
|
||||
|
||||
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
|
||||
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(true)
|
||||
) -> io::Result<ShellHandle<'de, D>> {
|
||||
Ok(Shell::read(&mut BytesBinarySource::new(s.as_bytes()).text(), true, decode_embedded)?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -266,9 +266,9 @@ impl<'de, S: BinarySource<'de>> TextReader<'de, S>
|
|||
return match NUMBER_RE.captures(&s) {
|
||||
None => Ok(Atom::Symbol(s.into())),
|
||||
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!(
|
||||
"Invalid signed-integer number: {:?}", s)))?.into())),
|
||||
"Invalid signed-integer number: {:?}", s)))?.into()))),
|
||||
Some(_) => {
|
||||
if let Some(maybe_f) = m.get(7) {
|
||||
let s = m[1].to_owned() + &m[3];
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use crate::DomainEncode;
|
||||
use crate::IOValue;
|
||||
use crate::IOValueDomainCodec;
|
||||
use crate::ValueImpl;
|
||||
use crate::Writer;
|
||||
use crate::hex::HexFormatter;
|
||||
|
@ -56,10 +54,6 @@ impl TextWriter<&mut Vec<u8>> {
|
|||
v.write(&mut TextWriter::new(&mut buf), enc)?;
|
||||
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> {
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::io;
|
|||
use crate::AtomClass;
|
||||
use crate::CompoundClass;
|
||||
use crate::DomainEncode;
|
||||
use crate::IOValueDomainCodec;
|
||||
use crate::IOValueDomainEncode;
|
||||
use crate::SignedInteger;
|
||||
use crate::ValueClass;
|
||||
use crate::boundary as B;
|
||||
|
@ -86,7 +86,7 @@ pub fn write_value<V: ValueImpl>(
|
|||
for ann in &anns[..] {
|
||||
annotation_b.shift(Some(B::Item::Annotation));
|
||||
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));
|
||||
w.boundary(&annotation_b)?;
|
||||
|
|
Loading…
Reference in New Issue