use std::iter::FromIterator;
use crate::{Array, Item, Table};
#[derive(Clone, Debug, Default)]
pub struct ArrayOfTables {
pub(crate) span: Option<std::ops::Range<usize>>,
pub(crate) values: Vec<Item>,
}
impl ArrayOfTables {
pub fn new() -> Self {
Default::default()
}
}
impl ArrayOfTables {
pub fn into_array(mut self) -> Array {
for value in self.values.iter_mut() {
value.make_value();
}
let mut a = Array::with_vec(self.values);
a.fmt();
a
}
pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
self.span.clone()
}
pub(crate) fn despan(&mut self, input: &str) {
self.span = None;
for value in &mut self.values {
value.despan(input);
}
}
}
impl ArrayOfTables {
pub fn iter(&self) -> ArrayOfTablesIter<'_> {
Box::new(self.values.iter().filter_map(Item::as_table))
}
pub fn iter_mut(&mut self) -> ArrayOfTablesIterMut<'_> {
Box::new(self.values.iter_mut().filter_map(Item::as_table_mut))
}
pub fn len(&self) -> usize {
self.values.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn clear(&mut self) {
self.values.clear()
}
pub fn get(&self, index: usize) -> Option<&Table> {
self.values.get(index).and_then(Item::as_table)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut Table> {
self.values.get_mut(index).and_then(Item::as_table_mut)
}
pub fn push(&mut self, table: Table) {
self.values.push(Item::Table(table));
}
pub fn remove(&mut self, index: usize) {
self.values.remove(index);
}
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&Table) -> bool,
{
self.values
.retain(|item| item.as_table().map(&mut keep).unwrap_or(false));
}
}
pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>;
pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>;
pub type ArrayOfTablesIntoIter = Box<dyn Iterator<Item = Table>>;
impl Extend<Table> for ArrayOfTables {
fn extend<T: IntoIterator<Item = Table>>(&mut self, iter: T) {
for value in iter {
self.push(value);
}
}
}
impl FromIterator<Table> for ArrayOfTables {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Table>,
{
let v = iter.into_iter().map(Item::Table);
ArrayOfTables {
values: v.collect(),
span: None,
}
}
}
impl IntoIterator for ArrayOfTables {
type Item = Table;
type IntoIter = ArrayOfTablesIntoIter;
fn into_iter(self) -> Self::IntoIter {
Box::new(
self.values
.into_iter()
.filter(|v| v.is_table())
.map(|v| v.into_table().unwrap()),
)
}
}
impl<'s> IntoIterator for &'s ArrayOfTables {
type Item = &'s Table;
type IntoIter = ArrayOfTablesIter<'s>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl std::fmt::Display for ArrayOfTables {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.clone().into_array().fmt(f)
}
}