summaryrefslogtreecommitdiff
path: root/src/eval/array.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-07-29 12:01:06 +0200
committerLaurenz <laurmaedje@gmail.com>2021-07-29 12:01:06 +0200
commit853361338bd756c23992041511b1836a2cd0647f (patch)
tree335e632ed0de6090d3139b5f39d02d03ba471bad /src/eval/array.rs
parent312dcd070cf79c1dd5503f90ef10588fe4612108 (diff)
Better addition and iteration for array, dict and template
Diffstat (limited to 'src/eval/array.rs')
-rw-r--r--src/eval/array.rs62
1 files changed, 36 insertions, 26 deletions
diff --git a/src/eval/array.rs b/src/eval/array.rs
index f62bda9f..38876c96 100644
--- a/src/eval/array.rs
+++ b/src/eval/array.rs
@@ -73,11 +73,6 @@ impl Array {
Rc::make_mut(&mut self.vec).push(value);
}
- /// Extend the array with the values from another array.
- pub fn extend(&mut self, other: &Array) {
- Rc::make_mut(&mut self.vec).extend(other.into_iter())
- }
-
/// Clear the array.
pub fn clear(&mut self) {
if Rc::strong_count(&mut self.vec) == 1 {
@@ -90,19 +85,13 @@ impl Array {
/// Repeat this array `n` times.
pub fn repeat(&self, n: usize) -> Self {
let len = self.len().checked_mul(n).expect("capacity overflow");
- self.into_iter().cycle().take(len).collect()
+ self.iter().cloned().cycle().take(len).collect()
}
/// Iterate over references to the contained values.
pub fn iter(&self) -> std::slice::Iter<Value> {
self.vec.iter()
}
-
- /// Iterate over the contained values.
- pub fn into_iter(&self) -> impl Iterator<Item = Value> + Clone + '_ {
- // TODO: Actually consume the vector if the ref-count is 1?
- self.iter().cloned()
- }
}
impl Default for Array {
@@ -117,32 +106,53 @@ impl Debug for Array {
}
}
+impl Add for Array {
+ type Output = Self;
+
+ fn add(mut self, rhs: Array) -> Self::Output {
+ self += rhs;
+ self
+ }
+}
+
+impl AddAssign for Array {
+ fn add_assign(&mut self, rhs: Array) {
+ match Rc::try_unwrap(rhs.vec) {
+ Ok(vec) => self.extend(vec),
+ Err(rc) => self.extend(rc.iter().cloned()),
+ }
+ }
+}
+
impl FromIterator<Value> for Array {
fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
Array { vec: Rc::new(iter.into_iter().collect()) }
}
}
-impl<'a> IntoIterator for &'a Array {
- type Item = &'a Value;
- type IntoIter = std::slice::Iter<'a, Value>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
+impl Extend<Value> for Array {
+ fn extend<T: IntoIterator<Item = Value>>(&mut self, iter: T) {
+ Rc::make_mut(&mut self.vec).extend(iter);
}
}
-impl Add<&Array> for Array {
- type Output = Self;
+impl IntoIterator for Array {
+ type Item = Value;
+ type IntoIter = std::vec::IntoIter<Value>;
- fn add(mut self, rhs: &Array) -> Self::Output {
- self.extend(rhs);
- self
+ fn into_iter(self) -> Self::IntoIter {
+ match Rc::try_unwrap(self.vec) {
+ Ok(vec) => vec.into_iter(),
+ Err(rc) => (*rc).clone().into_iter(),
+ }
}
}
-impl AddAssign<&Array> for Array {
- fn add_assign(&mut self, rhs: &Array) {
- self.extend(rhs);
+impl<'a> IntoIterator for &'a Array {
+ type Item = &'a Value;
+ type IntoIter = std::slice::Iter<'a, Value>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
}
}