• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::iter::FromIterator;
2 
3 use crate::{Array, Item, Table};
4 
5 /// Type representing a TOML array of tables
6 #[derive(Clone, Debug, Default)]
7 pub 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`
16 impl ArrayOfTables {
17     /// Creates an empty array of tables.
new() -> Self18     pub fn new() -> Self {
19         Default::default()
20     }
21 }
22 
23 /// Formatting
24 impl ArrayOfTables {
25     /// Convert to an inline array
into_array(mut self) -> Array26     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].
span(&self) -> Option<std::ops::Range<usize>>38     pub fn span(&self) -> Option<std::ops::Range<usize>> {
39         self.span.clone()
40     }
41 
despan(&mut self, input: &str)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 
50 impl ArrayOfTables {
51     /// Returns an iterator over tables.
iter(&self) -> ArrayOfTablesIter<'_>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.
iter_mut(&mut self) -> ArrayOfTablesIterMut<'_>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()`.
len(&self) -> usize63     pub fn len(&self) -> usize {
64         self.values.len()
65     }
66 
67     /// Returns true if `self.len() == 0`.
is_empty(&self) -> bool68     pub fn is_empty(&self) -> bool {
69         self.len() == 0
70     }
71 
72     /// Removes all the tables.
clear(&mut self)73     pub fn clear(&mut self) {
74         self.values.clear();
75     }
76 
77     /// Returns an optional reference to the table.
get(&self, index: usize) -> Option<&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.
get_mut(&mut self, index: usize) -> Option<&mut 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.
push(&mut self, table: Table)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.
remove(&mut self, index: usize)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.
retain<F>(&mut self, mut keep: F) where F: FnMut(&Table) -> bool,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.
113 pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>;
114 /// An iterator type over `ArrayOfTables`'s values.
115 pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>;
116 /// An iterator type over `ArrayOfTables`'s values.
117 pub type ArrayOfTablesIntoIter = Box<dyn Iterator<Item = Table>>;
118 
119 impl Extend<Table> for ArrayOfTables {
extend<T: IntoIterator<Item = Table>>(&mut self, iter: T)120     fn extend<T: IntoIterator<Item = Table>>(&mut self, iter: T) {
121         for value in iter {
122             self.push(value);
123         }
124     }
125 }
126 
127 impl FromIterator<Table> for ArrayOfTables {
from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = Table>,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 
140 impl IntoIterator for ArrayOfTables {
141     type Item = Table;
142     type IntoIter = ArrayOfTablesIntoIter;
143 
into_iter(self) -> Self::IntoIter144     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 
154 impl<'s> IntoIterator for &'s ArrayOfTables {
155     type Item = &'s Table;
156     type IntoIter = ArrayOfTablesIter<'s>;
157 
into_iter(self) -> Self::IntoIter158     fn into_iter(self) -> Self::IntoIter {
159         self.iter()
160     }
161 }
162 
163 #[cfg(feature = "display")]
164 impl std::fmt::Display for ArrayOfTables {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result165     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 }
170