From 29a882f9537e497319934e697d0668eb4dbfa7da Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Thu, 30 Sep 2021 11:15:26 +0200 Subject: [PATCH] Shrink commonest annotationless representation --- .../rust/preserves/src/value/repr.rs | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/implementations/rust/preserves/src/value/repr.rs b/implementations/rust/preserves/src/value/repr.rs index d41e66b..07cdfb7 100644 --- a/implementations/rust/preserves/src/value/repr.rs +++ b/implementations/rust/preserves/src/value/repr.rs @@ -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(Option>); +pub struct Annotations(Option>>); impl Annotations { pub fn empty() -> Self { @@ -1015,7 +1015,7 @@ impl Annotations { } pub fn new(anns: Option>) -> Self { - Annotations(anns) + Annotations(anns.map(Box::new)) } pub fn maybe_slice(&self) -> Option<&[N]> { @@ -1030,16 +1030,30 @@ impl Annotations { } pub fn to_vec(self) -> Vec { - 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(&mut self, f: F) -> &mut Self where F: FnOnce(&mut Vec) { - let mut v: Vec = 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 Annotations { None => Annotations(None), Some(b) => - Annotations(Some(b.iter().map(|a| a.copy_via(f)).collect::, _>>()?)), + Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect::, _>>()?))), }) } }