toml_edit/
array_of_tables.rs

1use std::iter::FromIterator;
2
3use crate::{Array, Item, Table};
4
5/// Type representing a TOML array of tables
6#[derive(Clone, Debug, Default)]
7pub struct ArrayOfTables {
8    // Always Vec<Item::Table>, just `Item` to make `Index` work
9    pub(crate) span: Option<std::ops::Range<usize>>,
10    pub(crate) values: Vec<Item>,
11}
12
13/// Constructors
14///
15/// See also `FromIterator`
16impl ArrayOfTables {
17    /// Creates an empty array of tables.
18    pub fn new() -> Self {
19        Default::default()
20    }
21}
22
23/// Formatting
24impl ArrayOfTables {
25    /// Convert to an inline array
26    pub fn into_array(mut self) -> Array {
27        for value in self.values.iter_mut() {
28            value.make_value();
29        }
30        let mut a = Array::with_vec(self.values);
31        a.fmt();
32        a
33    }
34
35    /// Returns the location within the original document
36    pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
37        self.span.clone()
38    }
39
40    pub(crate) fn despan(&mut self, input: &str) {
41        self.span = None;
42        for value in &mut self.values {
43            value.despan(input);
44        }
45    }
46}
47
48impl ArrayOfTables {
49    /// Returns an iterator over tables.
50    pub fn iter(&self) -> ArrayOfTablesIter<'_> {
51        Box::new(self.values.iter().filter_map(Item::as_table))
52    }
53
54    /// Returns an iterator over tables.
55    pub fn iter_mut(&mut self) -> ArrayOfTablesIterMut<'_> {
56        Box::new(self.values.iter_mut().filter_map(Item::as_table_mut))
57    }
58
59    /// Returns the length of the underlying Vec.
60    /// To get the actual number of items use `a.iter().count()`.
61    pub fn len(&self) -> usize {
62        self.values.len()
63    }
64
65    /// Returns true iff `self.len() == 0`.
66    pub fn is_empty(&self) -> bool {
67        self.len() == 0
68    }
69
70    /// Removes all the tables.
71    pub fn clear(&mut self) {
72        self.values.clear()
73    }
74
75    /// Returns an optional reference to the table.
76    pub fn get(&self, index: usize) -> Option<&Table> {
77        self.values.get(index).and_then(Item::as_table)
78    }
79
80    /// Returns an optional mutable reference to the table.
81    pub fn get_mut(&mut self, index: usize) -> Option<&mut Table> {
82        self.values.get_mut(index).and_then(Item::as_table_mut)
83    }
84
85    /// Appends a table to the array.
86    pub fn push(&mut self, table: Table) {
87        self.values.push(Item::Table(table));
88    }
89
90    /// Removes a table with the given index.
91    pub fn remove(&mut self, index: usize) {
92        self.values.remove(index);
93    }
94}
95
96/// An iterator type over `ArrayOfTables`'s values.
97pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>;
98/// An iterator type over `ArrayOfTables`'s values.
99pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>;
100/// An iterator type over `ArrayOfTables`'s values.
101pub type ArrayOfTablesIntoIter = Box<dyn Iterator<Item = Table>>;
102
103impl Extend<Table> for ArrayOfTables {
104    fn extend<T: IntoIterator<Item = Table>>(&mut self, iter: T) {
105        for value in iter {
106            self.push(value);
107        }
108    }
109}
110
111impl FromIterator<Table> for ArrayOfTables {
112    fn from_iter<I>(iter: I) -> Self
113    where
114        I: IntoIterator<Item = Table>,
115    {
116        let v = iter.into_iter().map(Item::Table);
117        ArrayOfTables {
118            values: v.collect(),
119            span: None,
120        }
121    }
122}
123
124impl IntoIterator for ArrayOfTables {
125    type Item = Table;
126    type IntoIter = ArrayOfTablesIntoIter;
127
128    fn into_iter(self) -> Self::IntoIter {
129        Box::new(
130            self.values
131                .into_iter()
132                .filter(|v| v.is_table())
133                .map(|v| v.into_table().unwrap()),
134        )
135    }
136}
137
138impl<'s> IntoIterator for &'s ArrayOfTables {
139    type Item = &'s Table;
140    type IntoIter = ArrayOfTablesIter<'s>;
141
142    fn into_iter(self) -> Self::IntoIter {
143        self.iter()
144    }
145}
146
147impl std::fmt::Display for ArrayOfTables {
148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149        // HACK: Without the header, we don't really have a proper way of printing this
150        self.clone().into_array().fmt(f)
151    }
152}