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    /// The location within the original document
36    ///
37    /// This generally requires an [`ImDocument`][crate::ImDocument].
38    pub fn span(&self) -> Option<std::ops::Range<usize>> {
39        self.span.clone()
40    }
41
42    pub(crate) fn despan(&mut self, input: &str) {
43        self.span = None;
44        for value in &mut self.values {
45            value.despan(input);
46        }
47    }
48}
49
50impl ArrayOfTables {
51    /// Returns an iterator over tables.
52    pub fn iter(&self) -> ArrayOfTablesIter<'_> {
53        Box::new(self.values.iter().filter_map(Item::as_table))
54    }
55
56    /// Returns an iterator over tables.
57    pub fn iter_mut(&mut self) -> ArrayOfTablesIterMut<'_> {
58        Box::new(self.values.iter_mut().filter_map(Item::as_table_mut))
59    }
60
61    /// Returns the length of the underlying Vec.
62    /// To get the actual number of items use `a.iter().count()`.
63    pub fn len(&self) -> usize {
64        self.values.len()
65    }
66
67    /// Returns true if `self.len() == 0`.
68    pub fn is_empty(&self) -> bool {
69        self.len() == 0
70    }
71
72    /// Removes all the tables.
73    pub fn clear(&mut self) {
74        self.values.clear();
75    }
76
77    /// Returns an optional reference to the table.
78    pub fn get(&self, index: usize) -> Option<&Table> {
79        self.values.get(index).and_then(Item::as_table)
80    }
81
82    /// Returns an optional mutable reference to the table.
83    pub fn get_mut(&mut self, index: usize) -> Option<&mut Table> {
84        self.values.get_mut(index).and_then(Item::as_table_mut)
85    }
86
87    /// Appends a table to the array.
88    pub fn push(&mut self, table: Table) {
89        self.values.push(Item::Table(table));
90    }
91
92    /// Removes a table with the given index.
93    pub fn remove(&mut self, index: usize) {
94        self.values.remove(index);
95    }
96
97    /// Retains only the elements specified by the `keep` predicate.
98    ///
99    /// In other words, remove all tables for which `keep(&table)` returns `false`.
100    ///
101    /// This method operates in place, visiting each element exactly once in the
102    /// original order, and preserves the order of the retained elements.
103    pub fn retain<F>(&mut self, mut keep: F)
104    where
105        F: FnMut(&Table) -> bool,
106    {
107        self.values
108            .retain(|item| item.as_table().map(&mut keep).unwrap_or(false));
109    }
110}
111
112/// An iterator type over `ArrayOfTables`'s values.
113pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>;
114/// An iterator type over `ArrayOfTables`'s values.
115pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>;
116/// An iterator type over `ArrayOfTables`'s values.
117pub type ArrayOfTablesIntoIter = Box<dyn Iterator<Item = Table>>;
118
119impl Extend<Table> for ArrayOfTables {
120    fn extend<T: IntoIterator<Item = Table>>(&mut self, iter: T) {
121        for value in iter {
122            self.push(value);
123        }
124    }
125}
126
127impl FromIterator<Table> for ArrayOfTables {
128    fn from_iter<I>(iter: I) -> Self
129    where
130        I: IntoIterator<Item = Table>,
131    {
132        let v = iter.into_iter().map(Item::Table);
133        ArrayOfTables {
134            values: v.collect(),
135            span: None,
136        }
137    }
138}
139
140impl IntoIterator for ArrayOfTables {
141    type Item = Table;
142    type IntoIter = ArrayOfTablesIntoIter;
143
144    fn into_iter(self) -> Self::IntoIter {
145        Box::new(
146            self.values
147                .into_iter()
148                .filter(|v| v.is_table())
149                .map(|v| v.into_table().unwrap()),
150        )
151    }
152}
153
154impl<'s> IntoIterator for &'s ArrayOfTables {
155    type Item = &'s Table;
156    type IntoIter = ArrayOfTablesIter<'s>;
157
158    fn into_iter(self) -> Self::IntoIter {
159        self.iter()
160    }
161}
162
163#[cfg(feature = "display")]
164impl std::fmt::Display for ArrayOfTables {
165    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166        // HACK: Without the header, we don't really have a proper way of printing this
167        self.clone().into_array().fmt(f)
168    }
169}