summaryrefslogtreecommitdiffstats
path: root/vendor/tabled/src/grid/records
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tabled/src/grid/records')
-rw-r--r--vendor/tabled/src/grid/records/empty_records.rs41
-rw-r--r--vendor/tabled/src/grid/records/into_records/buf_records.rs213
-rw-r--r--vendor/tabled/src/grid/records/into_records/either_string.rs22
-rw-r--r--vendor/tabled/src/grid/records/into_records/limit_column_records.rs82
-rw-r--r--vendor/tabled/src/grid/records/into_records/limit_row_records.rs59
-rw-r--r--vendor/tabled/src/grid/records/into_records/mod.rs26
-rw-r--r--vendor/tabled/src/grid/records/into_records/truncate_records.rs136
-rw-r--r--vendor/tabled/src/grid/records/mod.rs19
-rw-r--r--vendor/tabled/src/grid/records/records_mut.rs34
-rw-r--r--vendor/tabled/src/grid/records/resizable.rs217
10 files changed, 849 insertions, 0 deletions
diff --git a/vendor/tabled/src/grid/records/empty_records.rs b/vendor/tabled/src/grid/records/empty_records.rs
new file mode 100644
index 000000000..77ebc812d
--- /dev/null
+++ b/vendor/tabled/src/grid/records/empty_records.rs
@@ -0,0 +1,41 @@
+//! An empty [`Records`] implementation.
+
+use core::iter::{repeat, Repeat, Take};
+
+use super::Records;
+
+/// Empty representation of [`Records`].
+#[derive(Debug, Default, Clone)]
+pub struct EmptyRecords {
+ rows: usize,
+ cols: usize,
+}
+
+impl EmptyRecords {
+ /// Constructs an empty representation of [`Records`] with a given shape.
+ pub fn new(rows: usize, cols: usize) -> Self {
+ Self { rows, cols }
+ }
+}
+
+impl From<(usize, usize)> for EmptyRecords {
+ fn from((count_rows, count_columns): (usize, usize)) -> Self {
+ Self::new(count_rows, count_columns)
+ }
+}
+
+impl Records for EmptyRecords {
+ type Iter = Take<Repeat<Take<Repeat<&'static str>>>>;
+
+ fn iter_rows(self) -> Self::Iter {
+ repeat(repeat("").take(self.cols)).take(self.rows)
+ }
+
+ fn count_columns(&self) -> usize {
+ self.cols
+ }
+
+ fn hint_count_rows(&self) -> Option<usize> {
+ Some(self.rows)
+ }
+}
diff --git a/vendor/tabled/src/grid/records/into_records/buf_records.rs b/vendor/tabled/src/grid/records/into_records/buf_records.rs
new file mode 100644
index 000000000..2db3e45bf
--- /dev/null
+++ b/vendor/tabled/src/grid/records/into_records/buf_records.rs
@@ -0,0 +1,213 @@
+//! A module contains [`BufRows`] and [`BufColumns`] iterators.
+//!
+//! Almoust always they both can be used interchangeably but [`BufRows`] is supposed to be lighter cause it
+//! does not reads columns.
+
+use crate::grid::records::IntoRecords;
+
+use super::either_string::EitherString;
+
+/// BufRecords inspects [`IntoRecords`] iterator and keeps read data buffered.
+/// So it can be checking before hand.
+#[derive(Debug)]
+pub struct BufRows<I, T> {
+ iter: I,
+ buf: Vec<T>,
+}
+
+impl BufRows<(), ()> {
+ /// Creates a new [`BufRows`] structure, filling the buffer.
+ pub fn new<I: IntoRecords>(
+ records: I,
+ sniff: usize,
+ ) -> BufRows<<I::IterRows as IntoIterator>::IntoIter, I::IterColumns> {
+ let mut buf = vec![];
+
+ let mut iter = records.iter_rows().into_iter();
+ for _ in 0..sniff {
+ match iter.next() {
+ Some(row) => buf.push(row),
+ None => break,
+ }
+ }
+
+ BufRows { iter, buf }
+ }
+}
+
+impl<I, T> BufRows<I, T> {
+ /// Returns a slice of a record buffer.
+ pub fn as_slice(&self) -> &[T] {
+ &self.buf
+ }
+}
+
+impl<I, T> From<BufRows<I, T>> for BufColumns<I>
+where
+ T: IntoIterator,
+ T::Item: AsRef<str>,
+{
+ fn from(value: BufRows<I, T>) -> Self {
+ let buf = value
+ .buf
+ .into_iter()
+ .map(|row| row.into_iter().map(|s| s.as_ref().to_string()).collect())
+ .collect();
+
+ BufColumns {
+ iter: value.iter,
+ buf,
+ }
+ }
+}
+
+impl<I, T> IntoRecords for BufRows<I, T>
+where
+ I: Iterator<Item = T>,
+ T: IntoIterator,
+ T::Item: AsRef<str>,
+{
+ type Cell = T::Item;
+ type IterColumns = T;
+ type IterRows = BufRowIter<I, T>;
+
+ fn iter_rows(self) -> Self::IterRows {
+ BufRowIter {
+ buf: self.buf.into_iter(),
+ iter: self.iter,
+ }
+ }
+}
+
+/// Buffered [`Iterator`].
+#[derive(Debug)]
+pub struct BufRowIter<I, T> {
+ buf: std::vec::IntoIter<T>,
+ iter: I,
+}
+
+impl<I, T> Iterator for BufRowIter<I, T>
+where
+ I: Iterator<Item = T>,
+ T: IntoIterator,
+ T::Item: AsRef<str>,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.buf.next() {
+ Some(i) => Some(i),
+ None => self.iter.next(),
+ }
+ }
+}
+
+/// BufRecords inspects [`IntoRecords`] iterator and keeps read data buffered.
+/// So it can be checking before hand.
+///
+/// In contrast to [`BufRows`] it keeps records by columns.
+#[derive(Debug)]
+pub struct BufColumns<I> {
+ iter: I,
+ buf: Vec<Vec<String>>,
+}
+
+impl BufColumns<()> {
+ /// Creates new [`BufColumns`] structure, filling the buffer.
+ pub fn new<I: IntoRecords>(
+ records: I,
+ sniff: usize,
+ ) -> BufColumns<<I::IterRows as IntoIterator>::IntoIter> {
+ let mut buf = vec![];
+
+ let mut iter = records.iter_rows().into_iter();
+ for _ in 0..sniff {
+ match iter.next() {
+ Some(row) => {
+ let row = row
+ .into_iter()
+ .map(|cell| cell.as_ref().to_string())
+ .collect::<Vec<_>>();
+ buf.push(row)
+ }
+ None => break,
+ }
+ }
+
+ BufColumns { iter, buf }
+ }
+}
+
+impl<I> BufColumns<I> {
+ /// Returns a slice of a keeping buffer.
+ pub fn as_slice(&self) -> &[Vec<String>] {
+ &self.buf
+ }
+}
+
+impl<I> IntoRecords for BufColumns<I>
+where
+ I: Iterator,
+ I::Item: IntoIterator,
+ <I::Item as IntoIterator>::Item: AsRef<str>,
+{
+ type Cell = EitherString<<I::Item as IntoIterator>::Item>;
+ type IterColumns = EitherRowIterator<<I::Item as IntoIterator>::IntoIter>;
+ type IterRows = BufColumnIter<I>;
+
+ fn iter_rows(self) -> Self::IterRows {
+ BufColumnIter {
+ buf: self.buf.into_iter(),
+ iter: self.iter,
+ }
+ }
+}
+
+/// A row iterator for [`BufColumns`]
+#[derive(Debug)]
+pub struct BufColumnIter<I> {
+ buf: std::vec::IntoIter<Vec<String>>,
+ iter: I,
+}
+
+impl<I> Iterator for BufColumnIter<I>
+where
+ I: Iterator,
+ I::Item: IntoIterator,
+ <I::Item as IntoIterator>::Item: AsRef<str>,
+{
+ type Item = EitherRowIterator<<I::Item as IntoIterator>::IntoIter>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.buf.next() {
+ Some(i) => Some(EitherRowIterator::Owned(i.into_iter())),
+ None => self
+ .iter
+ .next()
+ .map(|i| EitherRowIterator::Some(i.into_iter())),
+ }
+ }
+}
+
+/// An iterator over some iterator or allocated buffer.
+#[derive(Debug)]
+pub enum EitherRowIterator<I> {
+ /// Allocated iterator.
+ Owned(std::vec::IntoIter<String>),
+ /// Given iterator.
+ Some(I),
+}
+
+impl<I> Iterator for EitherRowIterator<I>
+where
+ I: Iterator,
+{
+ type Item = EitherString<I::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self {
+ EitherRowIterator::Owned(iter) => iter.next().map(EitherString::Owned),
+ EitherRowIterator::Some(iter) => iter.next().map(EitherString::Some),
+ }
+ }
+}
diff --git a/vendor/tabled/src/grid/records/into_records/either_string.rs b/vendor/tabled/src/grid/records/into_records/either_string.rs
new file mode 100644
index 000000000..f4d97290d
--- /dev/null
+++ b/vendor/tabled/src/grid/records/into_records/either_string.rs
@@ -0,0 +1,22 @@
+//! A module with a utility enum [`EitherString`].
+
+/// Either allocated string or some type which can be used as a string.
+#[derive(Debug)]
+pub enum EitherString<T> {
+ /// Allocated string.
+ Owned(String),
+ /// Something which can be used as a string.
+ Some(T),
+}
+
+impl<T> AsRef<str> for EitherString<T>
+where
+ T: AsRef<str>,
+{
+ fn as_ref(&self) -> &str {
+ match self {
+ EitherString::Owned(s) => s.as_ref(),
+ EitherString::Some(s) => s.as_ref(),
+ }
+ }
+}
diff --git a/vendor/tabled/src/grid/records/into_records/limit_column_records.rs b/vendor/tabled/src/grid/records/into_records/limit_column_records.rs
new file mode 100644
index 000000000..89b2b89ed
--- /dev/null
+++ b/vendor/tabled/src/grid/records/into_records/limit_column_records.rs
@@ -0,0 +1,82 @@
+//! The module contains [`LimitColumns`] records iterator.
+
+use crate::grid::records::IntoRecords;
+
+/// An iterator which limits amount of columns.
+#[derive(Debug)]
+pub struct LimitColumns<I> {
+ records: I,
+ limit: usize,
+}
+
+impl LimitColumns<()> {
+ /// Creates new [`LimitColumns`].
+ pub fn new<I: IntoRecords>(records: I, limit: usize) -> LimitColumns<I> {
+ LimitColumns { records, limit }
+ }
+}
+
+impl<I> IntoRecords for LimitColumns<I>
+where
+ I: IntoRecords,
+{
+ type Cell = I::Cell;
+ type IterColumns = LimitColumnsColumnsIter<<I::IterColumns as IntoIterator>::IntoIter>;
+ type IterRows = LimitColumnsIter<<I::IterRows as IntoIterator>::IntoIter>;
+
+ fn iter_rows(self) -> Self::IterRows {
+ LimitColumnsIter {
+ iter: self.records.iter_rows().into_iter(),
+ limit: self.limit,
+ }
+ }
+}
+
+/// An iterator over rows for [`LimitColumns`].
+#[derive(Debug)]
+pub struct LimitColumnsIter<I> {
+ iter: I,
+ limit: usize,
+}
+
+impl<I> Iterator for LimitColumnsIter<I>
+where
+ I: Iterator,
+ I::Item: IntoIterator,
+ <I::Item as IntoIterator>::Item: AsRef<str>,
+{
+ type Item = LimitColumnsColumnsIter<<I::Item as IntoIterator>::IntoIter>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let iter = self.iter.next()?;
+ Some(LimitColumnsColumnsIter {
+ iter: iter.into_iter(),
+ limit: self.limit,
+ })
+ }
+}
+
+/// An iterator over columns for [`LimitColumns`].
+#[derive(Debug)]
+pub struct LimitColumnsColumnsIter<I> {
+ iter: I,
+ limit: usize,
+}
+
+impl<I> Iterator for LimitColumnsColumnsIter<I>
+where
+ I: Iterator,
+ I::Item: AsRef<str>,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.limit == 0 {
+ return None;
+ }
+
+ self.limit -= 1;
+
+ self.iter.next()
+ }
+}
diff --git a/vendor/tabled/src/grid/records/into_records/limit_row_records.rs b/vendor/tabled/src/grid/records/into_records/limit_row_records.rs
new file mode 100644
index 000000000..a461c6682
--- /dev/null
+++ b/vendor/tabled/src/grid/records/into_records/limit_row_records.rs
@@ -0,0 +1,59 @@
+//! The module contains [`LimitRows`] records iterator.
+
+use crate::grid::records::IntoRecords;
+
+/// [`LimitRows`] is an records iterator which limits amount of rows.
+#[derive(Debug)]
+pub struct LimitRows<I> {
+ records: I,
+ limit: usize,
+}
+
+impl LimitRows<()> {
+ /// Creates new [`LimitRows`] iterator.
+ pub fn new<I: IntoRecords>(records: I, limit: usize) -> LimitRows<I> {
+ LimitRows { records, limit }
+ }
+}
+
+impl<I> IntoRecords for LimitRows<I>
+where
+ I: IntoRecords,
+{
+ type Cell = I::Cell;
+ type IterColumns = I::IterColumns;
+ type IterRows = LimitRowsIter<<I::IterRows as IntoIterator>::IntoIter>;
+
+ fn iter_rows(self) -> Self::IterRows {
+ LimitRowsIter {
+ iter: self.records.iter_rows().into_iter(),
+ limit: self.limit,
+ }
+ }
+}
+
+/// A rows iterator for [`LimitRows`]
+#[derive(Debug)]
+pub struct LimitRowsIter<I> {
+ iter: I,
+ limit: usize,
+}
+
+impl<I> Iterator for LimitRowsIter<I>
+where
+ I: Iterator,
+ I::Item: IntoIterator,
+ <I::Item as IntoIterator>::Item: AsRef<str>,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.limit == 0 {
+ return None;
+ }
+
+ self.limit -= 1;
+
+ self.iter.next()
+ }
+}
diff --git a/vendor/tabled/src/grid/records/into_records/mod.rs b/vendor/tabled/src/grid/records/into_records/mod.rs
new file mode 100644
index 000000000..0a52c41c1
--- /dev/null
+++ b/vendor/tabled/src/grid/records/into_records/mod.rs
@@ -0,0 +1,26 @@
+//! The module contains a list of helpers for [`IntoRecords`]
+//!
+//! [`IntoRecords`]: crate::grid::records::IntoRecords
+
+pub mod limit_column_records;
+pub mod limit_row_records;
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod buf_records;
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod either_string;
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod truncate_records;
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub use buf_records::{BufColumns, BufRows};
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub use truncate_records::TruncateContent;
+
+pub use limit_column_records::LimitColumns;
+pub use limit_row_records::LimitRows;
diff --git a/vendor/tabled/src/grid/records/into_records/truncate_records.rs b/vendor/tabled/src/grid/records/into_records/truncate_records.rs
new file mode 100644
index 000000000..17e7e533e
--- /dev/null
+++ b/vendor/tabled/src/grid/records/into_records/truncate_records.rs
@@ -0,0 +1,136 @@
+//! The module contains [`TruncateContent`] records iterator.
+
+use std::borrow::Cow;
+
+use crate::{
+ grid::records::IntoRecords, grid::util::string::string_width_multiline,
+ settings::width::Truncate,
+};
+
+use super::either_string::EitherString;
+
+/// A records iterator which truncates all cells to a given width.
+#[derive(Debug)]
+pub struct TruncateContent<'a, I> {
+ records: I,
+ width: ExactValue<'a>,
+}
+
+impl TruncateContent<'_, ()> {
+ /// Creates new [`TruncateContent`] object.
+ pub fn new<I: IntoRecords>(records: I, width: ExactValue<'_>) -> TruncateContent<'_, I> {
+ TruncateContent { records, width }
+ }
+}
+
+impl<'a, I> IntoRecords for TruncateContent<'a, I>
+where
+ I: IntoRecords,
+{
+ type Cell = EitherString<I::Cell>;
+ type IterColumns = TruncateContentColumnsIter<'a, <I::IterColumns as IntoIterator>::IntoIter>;
+ type IterRows = TruncateContentIter<'a, <I::IterRows as IntoIterator>::IntoIter>;
+
+ fn iter_rows(self) -> Self::IterRows {
+ TruncateContentIter {
+ iter: self.records.iter_rows().into_iter(),
+ width: self.width.clone(),
+ }
+ }
+}
+
+/// A row iterator for [`TruncateContent`].
+#[derive(Debug)]
+pub struct TruncateContentIter<'a, I> {
+ iter: I,
+ width: ExactValue<'a>,
+}
+
+impl<'a, I> Iterator for TruncateContentIter<'a, I>
+where
+ I: Iterator,
+ I::Item: IntoIterator,
+ <I::Item as IntoIterator>::Item: AsRef<str>,
+{
+ type Item = TruncateContentColumnsIter<'a, <I::Item as IntoIterator>::IntoIter>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let iter = self.iter.next()?;
+ Some(TruncateContentColumnsIter {
+ iter: iter.into_iter(),
+ current: 0,
+ width: self.width.clone(),
+ })
+ }
+}
+
+/// A column iterator for [`TruncateContent`].
+#[derive(Debug)]
+pub struct TruncateContentColumnsIter<'a, I> {
+ iter: I,
+ width: ExactValue<'a>,
+ current: usize,
+}
+
+impl<I> Iterator for TruncateContentColumnsIter<'_, I>
+where
+ I: Iterator,
+ I::Item: AsRef<str>,
+{
+ type Item = EitherString<I::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let s = self.iter.next()?;
+
+ let width = self.width.get(self.current);
+ self.current += 1;
+
+ let text_width = string_width_multiline(s.as_ref());
+ if text_width <= width {
+ return Some(EitherString::Some(s));
+ }
+
+ let text = Truncate::truncate_text(s.as_ref(), width);
+ let text = text.into_owned();
+ let text = EitherString::Owned(text);
+
+ Some(text)
+ }
+}
+
+/// A width value.
+#[derive(Debug, Clone)]
+pub enum ExactValue<'a> {
+ /// Const width value.
+ Exact(usize),
+ /// A list of width values for columns.
+ List(Cow<'a, [usize]>),
+}
+
+impl<'a> From<&'a [usize]> for ExactValue<'a> {
+ fn from(value: &'a [usize]) -> Self {
+ Self::List(value.into())
+ }
+}
+
+impl From<Vec<usize>> for ExactValue<'_> {
+ fn from(value: Vec<usize>) -> Self {
+ Self::List(value.into())
+ }
+}
+
+impl From<usize> for ExactValue<'_> {
+ fn from(value: usize) -> Self {
+ Self::Exact(value)
+ }
+}
+
+impl ExactValue<'_> {
+ /// Get a width by column.
+ pub fn get(&self, col: usize) -> usize {
+ match self {
+ ExactValue::Exact(val) => *val,
+ ExactValue::List(cols) => cols[col],
+ }
+ }
+}
diff --git a/vendor/tabled/src/grid/records/mod.rs b/vendor/tabled/src/grid/records/mod.rs
new file mode 100644
index 000000000..494002346
--- /dev/null
+++ b/vendor/tabled/src/grid/records/mod.rs
@@ -0,0 +1,19 @@
+//! The module contains [`Records`], [`ExactRecords`], [`RecordsMut`], [`Resizable`] traits
+//! and its implementations.
+//!
+//! Also it provies a list of helpers for a user built [`Records`] via [`into_records`].
+
+mod empty_records;
+mod records_mut;
+mod resizable;
+
+pub mod into_records;
+
+pub use empty_records::EmptyRecords;
+pub use papergrid::records::{ExactRecords, IntoRecords, IterRecords, PeekableRecords, Records};
+pub use records_mut::RecordsMut;
+pub use resizable::Resizable;
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub use papergrid::records::vec_records;
diff --git a/vendor/tabled/src/grid/records/records_mut.rs b/vendor/tabled/src/grid/records/records_mut.rs
new file mode 100644
index 000000000..38c42d2c7
--- /dev/null
+++ b/vendor/tabled/src/grid/records/records_mut.rs
@@ -0,0 +1,34 @@
+use crate::grid::config::Position;
+#[cfg(feature = "std")]
+use crate::grid::records::vec_records::{CellInfo, VecRecords};
+
+/// A [`Records`] representation which can modify cell by (row, column) index.
+///
+/// [`Records`]: crate::grid::records::Records
+pub trait RecordsMut<Text> {
+ /// Sets a text to a given cell by index.
+ fn set(&mut self, pos: Position, text: Text);
+}
+
+impl<T, Text> RecordsMut<Text> for &'_ mut T
+where
+ T: RecordsMut<Text>,
+{
+ fn set(&mut self, pos: Position, text: Text) {
+ T::set(self, pos, text)
+ }
+}
+
+#[cfg(feature = "std")]
+impl RecordsMut<String> for VecRecords<CellInfo<String>> {
+ fn set(&mut self, (row, col): Position, text: String) {
+ self[row][col] = CellInfo::new(text);
+ }
+}
+
+#[cfg(feature = "std")]
+impl RecordsMut<&str> for VecRecords<CellInfo<String>> {
+ fn set(&mut self, (row, col): Position, text: &str) {
+ self[row][col] = CellInfo::new(text.to_string());
+ }
+}
diff --git a/vendor/tabled/src/grid/records/resizable.rs b/vendor/tabled/src/grid/records/resizable.rs
new file mode 100644
index 000000000..29ab38038
--- /dev/null
+++ b/vendor/tabled/src/grid/records/resizable.rs
@@ -0,0 +1,217 @@
+use papergrid::config::Position;
+
+#[cfg(feature = "std")]
+use crate::grid::records::vec_records::VecRecords;
+
+/// A records representation which can be modified by moving rows/columns around.
+pub trait Resizable {
+ /// Swap cells with one another.
+ fn swap(&mut self, lhs: Position, rhs: Position);
+ /// Swap rows with one another.
+ fn swap_row(&mut self, lhs: usize, rhs: usize);
+ /// Swap columns with one another.
+ fn swap_column(&mut self, lhs: usize, rhs: usize);
+ /// Adds a new row to a data set.
+ fn push_row(&mut self);
+ /// Adds a new column to a data set.
+ fn push_column(&mut self);
+ /// Removes a row from a data set by index.
+ fn remove_row(&mut self, row: usize);
+ /// Removes a column from a data set by index.
+ fn remove_column(&mut self, column: usize);
+ /// Inserts a row at index.
+ fn insert_row(&mut self, row: usize);
+ /// Inserts column at index.
+ fn insert_column(&mut self, column: usize);
+}
+
+impl<T> Resizable for &'_ mut T
+where
+ T: Resizable,
+{
+ fn swap(&mut self, lhs: Position, rhs: Position) {
+ T::swap(self, lhs, rhs)
+ }
+
+ fn swap_row(&mut self, lhs: usize, rhs: usize) {
+ T::swap_row(self, lhs, rhs)
+ }
+
+ fn swap_column(&mut self, lhs: usize, rhs: usize) {
+ T::swap_column(self, lhs, rhs)
+ }
+
+ fn push_row(&mut self) {
+ T::push_row(self)
+ }
+
+ fn push_column(&mut self) {
+ T::push_column(self)
+ }
+
+ fn remove_row(&mut self, row: usize) {
+ T::remove_row(self, row)
+ }
+
+ fn remove_column(&mut self, column: usize) {
+ T::remove_column(self, column)
+ }
+
+ fn insert_row(&mut self, row: usize) {
+ T::insert_row(self, row)
+ }
+
+ fn insert_column(&mut self, column: usize) {
+ T::insert_column(self, column)
+ }
+}
+
+#[cfg(feature = "std")]
+impl<T> Resizable for Vec<Vec<T>>
+where
+ T: Default + Clone,
+{
+ fn swap(&mut self, lhs: Position, rhs: Position) {
+ if lhs == rhs {
+ return;
+ }
+
+ let t = std::mem::take(&mut self[lhs.0][lhs.1]);
+ let t = std::mem::replace(&mut self[rhs.0][rhs.1], t);
+ let _ = std::mem::replace(&mut self[lhs.0][lhs.1], t);
+ }
+
+ fn swap_row(&mut self, lhs: usize, rhs: usize) {
+ let t = std::mem::take(&mut self[lhs]);
+ let t = std::mem::replace(&mut self[rhs], t);
+ let _ = std::mem::replace(&mut self[lhs], t);
+ }
+
+ fn swap_column(&mut self, lhs: usize, rhs: usize) {
+ for row in self.iter_mut() {
+ row.swap(lhs, rhs);
+ }
+ }
+
+ fn push_row(&mut self) {
+ let count_columns = self.get(0).map(|l| l.len()).unwrap_or(0);
+ self.push(vec![T::default(); count_columns]);
+ }
+
+ fn push_column(&mut self) {
+ for row in self.iter_mut() {
+ row.push(T::default());
+ }
+ }
+
+ fn remove_row(&mut self, row: usize) {
+ let _ = self.remove(row);
+ }
+
+ fn remove_column(&mut self, column: usize) {
+ for row in self.iter_mut() {
+ let _ = row.remove(column);
+ }
+ }
+
+ fn insert_row(&mut self, row: usize) {
+ let count_columns = self.get(0).map(|l| l.len()).unwrap_or(0);
+ self.insert(row, vec![T::default(); count_columns]);
+ }
+
+ fn insert_column(&mut self, column: usize) {
+ for row in self {
+ row.insert(column, T::default());
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<T> Resizable for VecRecords<T>
+where
+ T: Default + Clone,
+{
+ fn swap(&mut self, lhs: Position, rhs: Position) {
+ if lhs == rhs {
+ return;
+ }
+
+ let t = std::mem::take(&mut self[lhs.0][lhs.1]);
+ let t = std::mem::replace(&mut self[rhs.0][rhs.1], t);
+ let _ = std::mem::replace(&mut self[lhs.0][lhs.1], t);
+ }
+
+ fn swap_row(&mut self, lhs: usize, rhs: usize) {
+ let t = std::mem::take(&mut self[lhs]);
+ let t = std::mem::replace(&mut self[rhs], t);
+ let _ = std::mem::replace(&mut self[lhs], t);
+ }
+
+ fn swap_column(&mut self, lhs: usize, rhs: usize) {
+ for row in self.iter_mut() {
+ row.swap(lhs, rhs);
+ }
+ }
+
+ fn push_row(&mut self) {
+ let records = std::mem::replace(self, VecRecords::new(vec![]));
+ let mut data: Vec<Vec<_>> = records.into();
+
+ let count_columns = data.get(0).map(|l| l.len()).unwrap_or(0);
+ data.push(vec![T::default(); count_columns]);
+
+ *self = VecRecords::new(data);
+ }
+
+ fn push_column(&mut self) {
+ let records = std::mem::replace(self, VecRecords::new(vec![]));
+ let mut data: Vec<Vec<_>> = records.into();
+
+ for row in &mut data {
+ row.push(T::default());
+ }
+
+ *self = VecRecords::new(data);
+ }
+
+ fn remove_row(&mut self, row: usize) {
+ let records = std::mem::replace(self, VecRecords::new(vec![]));
+ let mut data: Vec<Vec<_>> = records.into();
+
+ let _ = data.remove(row);
+
+ *self = VecRecords::new(data);
+ }
+
+ fn remove_column(&mut self, column: usize) {
+ let records = std::mem::replace(self, VecRecords::new(vec![]));
+ let mut data: Vec<Vec<_>> = records.into();
+
+ for row in &mut data {
+ let _ = row.remove(column);
+ }
+
+ *self = VecRecords::new(data);
+ }
+
+ fn insert_row(&mut self, row: usize) {
+ let records = std::mem::replace(self, VecRecords::new(vec![]));
+ let mut data: Vec<Vec<_>> = records.into();
+
+ let count_columns = data.get(0).map(|l| l.len()).unwrap_or(0);
+ data.insert(row, vec![T::default(); count_columns]);
+
+ *self = VecRecords::new(data);
+ }
+
+ fn insert_column(&mut self, column: usize) {
+ let records = std::mem::replace(self, VecRecords::new(vec![]));
+ let mut data: Vec<Vec<_>> = records.into();
+
+ for row in &mut data {
+ row.insert(column, T::default());
+ }
+
+ *self = VecRecords::new(data);
+ }
+}