Slim down the common case of no annotations
This commit is contained in:
parent
078e8dd4e8
commit
f2910eb8d0
|
@ -253,8 +253,8 @@ mod decoder_tests {
|
||||||
let mut buf = &b"\x0521"[..];
|
let mut buf = &b"\x0521"[..];
|
||||||
let mut d = decoder::from_bytes(&mut buf);
|
let mut d = decoder::from_bytes(&mut buf);
|
||||||
let v = d.demand_next().unwrap();
|
let v = d.demand_next().unwrap();
|
||||||
assert_eq!(v.annotations().len(), 1);
|
assert_eq!(v.annotations().slice().len(), 1);
|
||||||
assert_eq!(v.annotations()[0], Value::from(2).wrap());
|
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
|
||||||
assert_eq!(v.value(), &Value::from(1));
|
assert_eq!(v.value(), &Value::from(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ mod decoder_tests {
|
||||||
let mut d = decoder::from_bytes(&mut buf);
|
let mut d = decoder::from_bytes(&mut buf);
|
||||||
d.set_read_annotations(false);
|
d.set_read_annotations(false);
|
||||||
let v = d.demand_next().unwrap();
|
let v = d.demand_next().unwrap();
|
||||||
assert_eq!(v.annotations().len(), 0);
|
assert_eq!(v.annotations().slice().len(), 0);
|
||||||
assert_eq!(v.value(), &Value::from(1));
|
assert_eq!(v.value(), &Value::from(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,12 @@ impl<'a, W: Writer> Encoder<'a, W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&mut self, v: &IOValue) -> Result {
|
pub fn write(&mut self, v: &IOValue) -> Result {
|
||||||
for ann in v.annotations() {
|
match v.annotations().maybe_slice() {
|
||||||
self.write.write_annotation_prefix()?;
|
None => (),
|
||||||
self.write(ann)?;
|
Some(anns) => for ann in anns {
|
||||||
|
self.write.write_annotation_prefix()?;
|
||||||
|
self.write(ann)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.write_value(v.value())
|
self.write_value(v.value())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::io::{Read, Error};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
|
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
|
||||||
use super::signed_integer::SignedInteger;
|
use super::signed_integer::SignedInteger;
|
||||||
use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record};
|
use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations};
|
||||||
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_eof, io_syntax_error};
|
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_eof, io_syntax_error};
|
||||||
|
|
||||||
pub type IOResult<T> = std::result::Result<T, Error>;
|
pub type IOResult<T> = std::result::Result<T, Error>;
|
||||||
|
@ -592,8 +592,8 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
|
||||||
annotations.push(self.demand_next(read_annotations)?.into_owned());
|
annotations.push(self.demand_next(read_annotations)?.into_owned());
|
||||||
}
|
}
|
||||||
let (existing_annotations, v) = self.demand_next(read_annotations)?.into_owned().pieces();
|
let (existing_annotations, v) = self.demand_next(read_annotations)?.into_owned().pieces();
|
||||||
annotations.extend(existing_annotations);
|
annotations.extend_from_slice(existing_annotations.slice());
|
||||||
Cow::Owned(IOValue::wrap_ann(annotations, v))
|
Cow::Owned(IOValue::wrap(Annotations::new(Some(annotations)), v))
|
||||||
} else {
|
} else {
|
||||||
self.skip_value()?;
|
self.skip_value()?;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::convert::TryFrom;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::ops::IndexMut;
|
use std::ops::IndexMut;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
@ -26,16 +27,15 @@ pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
|
pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
|
||||||
fn wrap(v: Value<Self, D>) -> Self;
|
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self;
|
||||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self;
|
|
||||||
|
|
||||||
fn annotations(&self) -> &[Self];
|
fn annotations(&self) -> &Annotations<Self, D>;
|
||||||
fn value(&self) -> &Value<Self, D>;
|
fn value(&self) -> &Value<Self, D>;
|
||||||
fn pieces(self) -> (Vec<Self>, Value<Self, D>);
|
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>);
|
||||||
fn value_owned(self) -> Value<Self, D>;
|
fn value_owned(self) -> Value<Self, D>;
|
||||||
|
|
||||||
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
for ann in self.annotations() {
|
for ann in self.annotations().slice() {
|
||||||
write!(f, "@{:?} ", ann)?;
|
write!(f, "@{:?} ", ann)?;
|
||||||
}
|
}
|
||||||
self.value().fmt(f)
|
self.value().fmt(f)
|
||||||
|
@ -45,8 +45,7 @@ pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
|
||||||
where
|
where
|
||||||
F: Fn(&D) -> Value<M, E>
|
F: Fn(&D) -> Value<M, E>
|
||||||
{
|
{
|
||||||
M::wrap_ann(self.annotations().iter().map(|a| a.copy_via(f)).collect(),
|
M::wrap(self.annotations().copy_via(f), self.value().copy_via(f))
|
||||||
self.value().copy_via(f))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_io_value(&self) -> IOValue {
|
fn to_io_value(&self) -> IOValue {
|
||||||
|
@ -280,7 +279,7 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
|
||||||
|
|
||||||
impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
||||||
pub fn wrap(self) -> N {
|
pub fn wrap(self) -> N {
|
||||||
N::wrap(self)
|
N::wrap(Annotations::empty(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected(&self, k: ExpectedKind) -> Error {
|
fn expected(&self, k: ExpectedKind) -> Error {
|
||||||
|
@ -802,10 +801,64 @@ pub fn deserialize_nested_value<'de, D, N, Dom: Domain>(deserializer: D) ->
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Annotations<N: NestedValue<D>, D: Domain>(Option<Box<Vec<N>>>, PhantomData<D>);
|
||||||
|
|
||||||
|
impl<N: NestedValue<D>, D: Domain> Annotations<N, D> {
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Annotations(None,
|
||||||
|
PhantomData)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(anns: Option<Vec<N>>) -> Self {
|
||||||
|
Annotations(anns.and_then(|v| if v.is_empty() { None } else { Some(Box::new(v)) }),
|
||||||
|
PhantomData)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_slice(&self) -> Option<&[N]> {
|
||||||
|
match self.0 {
|
||||||
|
None => None,
|
||||||
|
Some(ref b) => Some(&&b[..]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slice(&self) -> &[N] {
|
||||||
|
self.maybe_slice().unwrap_or(&[])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modify<F>(&mut self, f: F) -> &mut Self
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Vec<N>)
|
||||||
|
{
|
||||||
|
let mut v: Vec<N> = self.0.take().map_or_else(|| vec![], |b| *b);
|
||||||
|
f(&mut v);
|
||||||
|
self.0 = if v.is_empty() { None } else { Some(Box::new(v)) };
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_via<M: NestedValue<E>, E: Domain, F>(&self, f: &F) -> Annotations<M, E>
|
||||||
|
where
|
||||||
|
F: Fn(&D) -> Value<M, E>
|
||||||
|
{
|
||||||
|
match self.0 {
|
||||||
|
None =>
|
||||||
|
Annotations(None, PhantomData),
|
||||||
|
Some(ref b) =>
|
||||||
|
Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect())), PhantomData),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An possibly-annotated Value, with annotations (themselves
|
/// An possibly-annotated Value, with annotations (themselves
|
||||||
/// possibly-annotated) in order of appearance.
|
/// possibly-annotated) in order of appearance.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Vec<N>, pub Value<N, D>);
|
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Annotations<N, D>, pub Value<N, D>);
|
||||||
|
|
||||||
|
impl<N: NestedValue<D>, D: Domain> AnnotatedValue<N, D> {
|
||||||
|
fn new(anns: Annotations<N, D>, value: Value<N, D>) -> Self {
|
||||||
|
AnnotatedValue(anns, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: NestedValue<D>, D: Domain> PartialEq for AnnotatedValue<N, D> {
|
impl<N: NestedValue<D>, D: Domain> PartialEq for AnnotatedValue<N, D> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
@ -839,7 +892,7 @@ impl<N: NestedValue<D>, D: Domain> Ord for AnnotatedValue<N, D> {
|
||||||
pub struct PlainValue<D: Domain>(AnnotatedValue<PlainValue<D>, D>);
|
pub struct PlainValue<D: Domain>(AnnotatedValue<PlainValue<D>, D>);
|
||||||
|
|
||||||
impl<D: Domain> PlainValue<D> {
|
impl<D: Domain> PlainValue<D> {
|
||||||
pub fn annotations_mut(&mut self) -> &mut Vec<Self> {
|
pub fn annotations_mut(&mut self) -> &mut Annotations<Self, D> {
|
||||||
&mut (self.0).0
|
&mut (self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,15 +902,11 @@ impl<D: Domain> PlainValue<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
||||||
fn wrap(v: Value<Self, D>) -> Self {
|
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
|
||||||
Self::wrap_ann(Vec::new(), v)
|
PlainValue(AnnotatedValue::new(anns, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
|
fn annotations(&self) -> &Annotations<Self, D> {
|
||||||
PlainValue(AnnotatedValue(anns, v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn annotations(&self) -> &[Self] {
|
|
||||||
&(self.0).0
|
&(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +914,7 @@ impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
||||||
&(self.0).1
|
&(self.0).1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pieces(self) -> (Vec<Self>, Value<Self, D>) {
|
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>) {
|
||||||
let AnnotatedValue(anns, v) = self.0;
|
let AnnotatedValue(anns, v) = self.0;
|
||||||
(anns, v)
|
(anns, v)
|
||||||
}
|
}
|
||||||
|
@ -901,15 +950,11 @@ use std::rc::Rc;
|
||||||
pub struct RcValue<D: Domain>(Rc<AnnotatedValue<RcValue<D>, D>>);
|
pub struct RcValue<D: Domain>(Rc<AnnotatedValue<RcValue<D>, D>>);
|
||||||
|
|
||||||
impl<D: Domain> NestedValue<D> for RcValue<D> {
|
impl<D: Domain> NestedValue<D> for RcValue<D> {
|
||||||
fn wrap(v: Value<Self, D>) -> Self {
|
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
|
||||||
Self::wrap_ann(Vec::new(), v)
|
RcValue(Rc::new(AnnotatedValue::new(anns, v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
|
fn annotations(&self) -> &Annotations<Self, D> {
|
||||||
RcValue(Rc::new(AnnotatedValue(anns, v)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn annotations(&self) -> &[Self] {
|
|
||||||
&(self.0).0
|
&(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +962,7 @@ impl<D: Domain> NestedValue<D> for RcValue<D> {
|
||||||
&(self.0).1
|
&(self.0).1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pieces(self) -> (Vec<Self>, Value<Self, D>) {
|
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>) {
|
||||||
match Rc::try_unwrap(self.0) {
|
match Rc::try_unwrap(self.0) {
|
||||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||||
Err(r) => (r.0.clone(), r.1.clone()),
|
Err(r) => (r.0.clone(), r.1.clone()),
|
||||||
|
@ -955,15 +1000,11 @@ use std::sync::Arc;
|
||||||
pub struct ArcValue<D: Domain>(Arc<AnnotatedValue<ArcValue<D>, D>>);
|
pub struct ArcValue<D: Domain>(Arc<AnnotatedValue<ArcValue<D>, D>>);
|
||||||
|
|
||||||
impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
||||||
fn wrap(v: Value<Self, D>) -> Self {
|
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
|
||||||
Self::wrap_ann(Vec::new(), v)
|
ArcValue(Arc::new(AnnotatedValue::new(anns, v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
|
fn annotations(&self) -> &Annotations<Self, D> {
|
||||||
ArcValue(Arc::new(AnnotatedValue(anns, v)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn annotations(&self) -> &[Self] {
|
|
||||||
&(self.0).0
|
&(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,7 +1012,7 @@ impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
||||||
&(self.0).1
|
&(self.0).1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pieces(self) -> (Vec<Self>, Value<Self, D>) {
|
fn pieces(self) -> (Annotations<Self, D>, Value<Self, D>) {
|
||||||
match Arc::try_unwrap(self.0) {
|
match Arc::try_unwrap(self.0) {
|
||||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||||
Err(r) => (r.0.clone(), r.1.clone()),
|
Err(r) => (r.0.clone(), r.1.clone()),
|
||||||
|
@ -1012,21 +1053,17 @@ pub struct IOValue(Arc<AnnotatedValue<IOValue, NullDomain>>);
|
||||||
pub type UnwrappedIOValue = Value<IOValue, NullDomain>;
|
pub type UnwrappedIOValue = Value<IOValue, NullDomain>;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Boolean(false))));
|
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(false))));
|
||||||
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Boolean(true))));
|
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(true))));
|
||||||
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Sequence(Vec::new()))));
|
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Sequence(Vec::new()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedValue<NullDomain> for IOValue {
|
impl NestedValue<NullDomain> for IOValue {
|
||||||
fn wrap(v: Value<Self, NullDomain>) -> Self {
|
fn wrap(anns: Annotations<Self, NullDomain>, v: Value<Self, NullDomain>) -> Self {
|
||||||
Self::wrap_ann(Vec::new(), v)
|
IOValue(Arc::new(AnnotatedValue::new(anns, v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, NullDomain>) -> Self {
|
fn annotations(&self) -> &Annotations<Self, NullDomain> {
|
||||||
IOValue(Arc::new(AnnotatedValue(anns, v)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn annotations(&self) -> &[Self] {
|
|
||||||
&(self.0).0
|
&(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,7 +1071,7 @@ impl NestedValue<NullDomain> for IOValue {
|
||||||
&(self.0).1
|
&(self.0).1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pieces(self) -> (Vec<Self>, Value<Self, NullDomain>) {
|
fn pieces(self) -> (Annotations<Self, NullDomain>, Value<Self, NullDomain>) {
|
||||||
match Arc::try_unwrap(self.0) {
|
match Arc::try_unwrap(self.0) {
|
||||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||||
Err(r) => (r.0.clone(), r.1.clone()),
|
Err(r) => (r.0.clone(), r.1.clone()),
|
||||||
|
|
Loading…
Reference in New Issue