More boulder-pushing

This commit is contained in:
Tony Garnock-Jones 2022-11-19 17:23:56 +01:00
parent 4070c5252d
commit 025c5bb962
15 changed files with 506 additions and 319 deletions

View File

@ -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)
}
}

View File

@ -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")
}

View File

@ -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())),
}
}
}
}

View File

@ -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;

View File

@ -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)?)
}

View File

@ -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};

View File

@ -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) {

View File

@ -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> {

View File

@ -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)),
}
}
}

View File

@ -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)
}
},

View File

@ -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)))
}
}

View File

@ -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)]

View File

@ -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];

View File

@ -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> {

View File

@ -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)?;