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 d = decoder::from_bytes(&mut buf);
|
||||
let v = d.demand_next().unwrap();
|
||||
assert_eq!(v.annotations().len(), 1);
|
||||
assert_eq!(v.annotations()[0], Value::from(2).wrap());
|
||||
assert_eq!(v.annotations().slice().len(), 1);
|
||||
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
|
||||
assert_eq!(v.value(), &Value::from(1));
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ mod decoder_tests {
|
|||
let mut d = decoder::from_bytes(&mut buf);
|
||||
d.set_read_annotations(false);
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,12 @@ impl<'a, W: Writer> Encoder<'a, W> {
|
|||
}
|
||||
|
||||
pub fn write(&mut self, v: &IOValue) -> Result {
|
||||
for ann in v.annotations() {
|
||||
self.write.write_annotation_prefix()?;
|
||||
self.write(ann)?;
|
||||
match v.annotations().maybe_slice() {
|
||||
None => (),
|
||||
Some(anns) => for ann in anns {
|
||||
self.write.write_annotation_prefix()?;
|
||||
self.write(ann)?;
|
||||
}
|
||||
}
|
||||
self.write_value(v.value())
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::io::{Read, Error};
|
|||
use std::marker::PhantomData;
|
||||
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
|
||||
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};
|
||||
|
||||
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());
|
||||
}
|
||||
let (existing_annotations, v) = self.demand_next(read_annotations)?.into_owned().pieces();
|
||||
annotations.extend(existing_annotations);
|
||||
Cow::Owned(IOValue::wrap_ann(annotations, v))
|
||||
annotations.extend_from_slice(existing_annotations.slice());
|
||||
Cow::Owned(IOValue::wrap(Annotations::new(Some(annotations)), v))
|
||||
} else {
|
||||
self.skip_value()?;
|
||||
continue;
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::convert::TryFrom;
|
|||
use std::convert::TryInto;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Index;
|
||||
use std::ops::IndexMut;
|
||||
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 {
|
||||
fn wrap(v: Value<Self, D>) -> Self;
|
||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self;
|
||||
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self;
|
||||
|
||||
fn annotations(&self) -> &[Self];
|
||||
fn annotations(&self) -> &Annotations<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 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)?;
|
||||
}
|
||||
self.value().fmt(f)
|
||||
|
@ -45,8 +45,7 @@ pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
|
|||
where
|
||||
F: Fn(&D) -> Value<M, E>
|
||||
{
|
||||
M::wrap_ann(self.annotations().iter().map(|a| a.copy_via(f)).collect(),
|
||||
self.value().copy_via(f))
|
||||
M::wrap(self.annotations().copy_via(f), self.value().copy_via(f))
|
||||
}
|
||||
|
||||
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> {
|
||||
pub fn wrap(self) -> N {
|
||||
N::wrap(self)
|
||||
N::wrap(Annotations::empty(), self)
|
||||
}
|
||||
|
||||
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
|
||||
/// possibly-annotated) in order of appearance.
|
||||
#[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> {
|
||||
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>);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -849,15 +902,11 @@ impl<D: Domain> PlainValue<D> {
|
|||
}
|
||||
|
||||
impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
||||
fn wrap(v: Value<Self, D>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
|
||||
PlainValue(AnnotatedValue::new(anns, v))
|
||||
}
|
||||
|
||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
|
||||
PlainValue(AnnotatedValue(anns, v))
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
fn annotations(&self) -> &Annotations<Self, D> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
|
@ -865,7 +914,7 @@ impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
|||
&(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;
|
||||
(anns, v)
|
||||
}
|
||||
|
@ -901,15 +950,11 @@ use std::rc::Rc;
|
|||
pub struct RcValue<D: Domain>(Rc<AnnotatedValue<RcValue<D>, D>>);
|
||||
|
||||
impl<D: Domain> NestedValue<D> for RcValue<D> {
|
||||
fn wrap(v: Value<Self, D>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
|
||||
RcValue(Rc::new(AnnotatedValue::new(anns, v)))
|
||||
}
|
||||
|
||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
|
||||
RcValue(Rc::new(AnnotatedValue(anns, v)))
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
fn annotations(&self) -> &Annotations<Self, D> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
|
@ -917,7 +962,7 @@ impl<D: Domain> NestedValue<D> for RcValue<D> {
|
|||
&(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) {
|
||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||
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>>);
|
||||
|
||||
impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
||||
fn wrap(v: Value<Self, D>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
fn wrap(anns: Annotations<Self, D>, v: Value<Self, D>) -> Self {
|
||||
ArcValue(Arc::new(AnnotatedValue::new(anns, v)))
|
||||
}
|
||||
|
||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self {
|
||||
ArcValue(Arc::new(AnnotatedValue(anns, v)))
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
fn annotations(&self) -> &Annotations<Self, D> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
|
@ -971,7 +1012,7 @@ impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
|||
&(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) {
|
||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||
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>;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Boolean(false))));
|
||||
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Boolean(true))));
|
||||
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Vec::new(), Value::Sequence(Vec::new()))));
|
||||
pub static ref FALSE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(false))));
|
||||
pub static ref TRUE: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Boolean(true))));
|
||||
pub static ref EMPTY_SEQ: IOValue = IOValue(Arc::new(AnnotatedValue(Annotations::empty(), Value::Sequence(Vec::new()))));
|
||||
}
|
||||
|
||||
impl NestedValue<NullDomain> for IOValue {
|
||||
fn wrap(v: Value<Self, NullDomain>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
fn wrap(anns: Annotations<Self, NullDomain>, v: Value<Self, NullDomain>) -> Self {
|
||||
IOValue(Arc::new(AnnotatedValue::new(anns, v)))
|
||||
}
|
||||
|
||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, NullDomain>) -> Self {
|
||||
IOValue(Arc::new(AnnotatedValue(anns, v)))
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
fn annotations(&self) -> &Annotations<Self, NullDomain> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
|
@ -1034,7 +1071,7 @@ impl NestedValue<NullDomain> for IOValue {
|
|||
&(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) {
|
||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||
Err(r) => (r.0.clone(), r.1.clone()),
|
||||
|
|
Loading…
Reference in New Issue