summaryrefslogtreecommitdiff
path: root/src/grid/row.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grid/row.rs')
-rw-r--r--src/grid/row.rs93
1 files changed, 72 insertions, 21 deletions
diff --git a/src/grid/row.rs b/src/grid/row.rs
index 72c79b02..ef27f040 100644
--- a/src/grid/row.rs
+++ b/src/grid/row.rs
@@ -16,9 +16,10 @@
use std::ops::{Index, IndexMut};
use std::ops::{Range, RangeTo, RangeFrom, RangeFull, RangeToInclusive};
-use std::cmp::{max, min};
+use std::cmp::{min, max};
use std::slice;
+use crate::grid::GridCell;
use crate::index::Column;
/// A row in the grid
@@ -43,7 +44,7 @@ impl<T: PartialEq> PartialEq for Row<T> {
}
}
-impl<T: Copy + Clone> Row<T> {
+impl<T: Copy> Row<T> {
pub fn new(columns: Column, template: &T) -> Row<T> {
Row {
inner: vec![*template; *columns],
@@ -52,52 +53,102 @@ impl<T: Copy + Clone> Row<T> {
}
pub fn grow(&mut self, cols: Column, template: &T) {
- assert!(self.len() < * cols);
+ if self.inner.len() >= cols.0 {
+ return;
+ }
+
+ self.inner.append(&mut vec![*template; cols.0 - self.len()]);
+ }
+
+ pub fn shrink(&mut self, cols: Column) -> Option<Vec<T>>
+ where
+ T: GridCell
+ {
+ if self.inner.len() <= cols.0 {
+ return None;
+ }
+
+ // Split off cells for a new row
+ let mut new_row = self.inner.split_off(cols.0);
+ let index = new_row.iter().rposition(|c| !c.is_empty()).map(|i| i + 1).unwrap_or(0);
+ new_row.truncate(index);
+
+ self.occ = min(self.occ, *cols);
- while self.len() != *cols {
- self.inner.push(*template);
+ if new_row.is_empty() {
+ None
+ } else {
+ Some(new_row)
}
}
/// Resets contents to the contents of `other`
#[inline(never)]
pub fn reset(&mut self, other: &T) {
- let occ = self.occ;
- for item in &mut self.inner[..occ] {
+ for item in &mut self.inner[..self.occ] {
*item = *other;
}
-
self.occ = 0;
}
}
#[allow(clippy::len_without_is_empty)]
impl<T> Row<T> {
- pub fn shrink(&mut self, cols: Column) {
- while self.len() != *cols {
- self.inner.pop();
+ #[inline]
+ pub fn from_vec(vec: Vec<T>, occ: usize) -> Row<T> {
+ Row {
+ inner: vec,
+ occ,
}
-
- self.occ = min(self.occ, *cols);
}
+ #[inline]
pub fn len(&self) -> usize {
self.inner.len()
}
- pub fn iter(&self) -> slice::Iter<'_, T> {
- self.inner.iter()
+ #[inline]
+ pub fn last(&self) -> Option<&T> {
+ self.inner.last()
}
-}
+ #[inline]
+ pub fn last_mut(&mut self) -> Option<&mut T> {
+ self.occ = self.inner.len();
+ self.inner.last_mut()
+ }
-impl<'a, T> IntoIterator for &'a Row<T> {
- type Item = &'a T;
- type IntoIter = slice::Iter<'a, T>;
+ #[inline]
+ pub fn append(&mut self, vec: &mut Vec<T>)
+ where
+ T: GridCell
+ {
+ self.inner.append(vec);
+ self.occ = self.inner.iter().rposition(|c| !c.is_empty()).map(|i| i + 1).unwrap_or(0);
+ }
#[inline]
- fn into_iter(self) -> slice::Iter<'a, T> {
- self.iter()
+ pub fn append_front(&mut self, mut vec: Vec<T>) {
+ self.occ += vec.len();
+ vec.append(&mut self.inner);
+ self.inner = vec;
+ }
+
+ #[inline]
+ pub fn is_empty(&self) -> bool
+ where
+ T: GridCell
+ {
+ self.inner.iter().all(|c| c.is_empty())
+ }
+
+ #[inline]
+ pub fn front_split_off(&mut self, at: usize) -> Vec<T> {
+ self.occ = self.occ.saturating_sub(at);
+
+ let mut split = self.inner.split_off(at);
+ std::mem::swap(&mut split, &mut self.inner);
+ split
}
}