Shrink commonest annotationless representation

This commit is contained in:
Tony Garnock-Jones 2021-09-30 11:15:26 +02:00
parent d1d52c2a30
commit 29a882f953
1 changed files with 22 additions and 8 deletions

View File

@ -75,7 +75,7 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
{
match &self.annotations().0 {
None => (),
Some(vs) => for v in vs { v.foreach_embedded(f)? },
Some(vs) => for v in vs.iter() { v.foreach_embedded(f)? },
}
self.value().foreach_embedded(f)
}
@ -1007,7 +1007,7 @@ impl<'de> serde::Deserialize<'de> for UnwrappedIOValue {
//---------------------------------------------------------------------------
#[derive(Clone)]
pub struct Annotations<N: NestedValue>(Option<Vec<N>>);
pub struct Annotations<N: NestedValue>(Option<Box<Vec<N>>>);
impl<N: NestedValue> Annotations<N> {
pub fn empty() -> Self {
@ -1015,7 +1015,7 @@ impl<N: NestedValue> Annotations<N> {
}
pub fn new(anns: Option<Vec<N>>) -> Self {
Annotations(anns)
Annotations(anns.map(Box::new))
}
pub fn maybe_slice(&self) -> Option<&[N]> {
@ -1030,16 +1030,30 @@ impl<N: NestedValue> Annotations<N> {
}
pub fn to_vec(self) -> Vec<N> {
self.0.unwrap_or_default()
use std::ops::DerefMut;
self.0.map(|mut b| std::mem::take(b.deref_mut())).unwrap_or_default()
}
pub fn modify<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&mut Vec<N>)
{
let mut v: Vec<N> = self.0.take().unwrap_or_else(Vec::new);
f(&mut v);
self.0 = if v.is_empty() { None } else { Some(v) };
match &mut self.0 {
None => {
let mut v = Vec::new();
f(&mut v);
if !v.is_empty() {
self.0 = Some(Box::new(v));
}
}
Some(b) => {
use std::ops::DerefMut;
f(b.deref_mut());
if b.is_empty() {
self.0 = None;
}
}
}
self
}
@ -1051,7 +1065,7 @@ impl<N: NestedValue> Annotations<N> {
None =>
Annotations(None),
Some(b) =>
Annotations(Some(b.iter().map(|a| a.copy_via(f)).collect::<Result<Vec<_>, _>>()?)),
Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect::<Result<Vec<_>, _>>()?))),
})
}
}