From 7e5d7eea9c580ef4b41a765bde624af431942b96 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:35 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- vendor/toml_edit/src/array.rs | 389 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 vendor/toml_edit/src/array.rs (limited to 'vendor/toml_edit/src/array.rs') diff --git a/vendor/toml_edit/src/array.rs b/vendor/toml_edit/src/array.rs new file mode 100644 index 000000000..68cb4467a --- /dev/null +++ b/vendor/toml_edit/src/array.rs @@ -0,0 +1,389 @@ +use std::iter::FromIterator; +use std::mem; + +use crate::repr::Decor; +use crate::value::{DEFAULT_LEADING_VALUE_DECOR, DEFAULT_VALUE_DECOR}; +use crate::{Item, RawString, Value}; + +/// Type representing a TOML array, +/// payload of the `Value::Array` variant's value +#[derive(Debug, Default, Clone)] +pub struct Array { + // `trailing` represents whitespaces, newlines + // and comments in an empty array or after the trailing comma + trailing: RawString, + trailing_comma: bool, + // prefix before `[` and suffix after `]` + decor: Decor, + pub(crate) span: Option>, + // always Vec + pub(crate) values: Vec, +} + +/// An owned iterator type over `Table`'s key/value pairs. +pub type ArrayIntoIter = Box>; +/// An iterator type over `Array`'s values. +pub type ArrayIter<'a> = Box + 'a>; +/// An iterator type over `Array`'s values. +pub type ArrayIterMut<'a> = Box + 'a>; + +/// Constructors +/// +/// See also `FromIterator` +impl Array { + /// Create an empty `Array` + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// ``` + pub fn new() -> Self { + Default::default() + } + + pub(crate) fn with_vec(values: Vec) -> Self { + Self { + values, + ..Default::default() + } + } +} + +/// Formatting +impl Array { + /// Auto formats the array. + pub fn fmt(&mut self) { + decorate_array(self); + } + + /// Set whether the array will use a trailing comma + pub fn set_trailing_comma(&mut self, yes: bool) { + self.trailing_comma = yes; + } + + /// Whether the array will use a trailing comma + pub fn trailing_comma(&self) -> bool { + self.trailing_comma + } + + /// Set whitespace after last element + pub fn set_trailing(&mut self, trailing: impl Into) { + self.trailing = trailing.into(); + } + + /// Whitespace after last element + pub fn trailing(&self) -> &RawString { + &self.trailing + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + &mut self.decor + } + + /// Returns the surrounding whitespace + pub fn decor(&self) -> &Decor { + &self.decor + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option> { + self.span.clone() + } + + pub(crate) fn despan(&mut self, input: &str) { + self.span = None; + self.decor.despan(input); + self.trailing.despan(input); + for value in &mut self.values { + value.despan(input); + } + } +} + +impl Array { + /// Returns an iterator over all values. + pub fn iter(&self) -> ArrayIter<'_> { + Box::new(self.values.iter().filter_map(Item::as_value)) + } + + /// Returns an iterator over all values. + pub fn iter_mut(&mut self) -> ArrayIterMut<'_> { + Box::new(self.values.iter_mut().filter_map(Item::as_value_mut)) + } + + /// Returns the length of the underlying Vec. + /// + /// In some rare cases, placeholder elements will exist. For a more accurate count, call + /// `a.iter().count()` + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// assert_eq!(arr.len(), 2); + /// ``` + pub fn len(&self) -> usize { + self.values.len() + } + + /// Return true iff `self.len() == 0`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// assert!(arr.is_empty()); + /// + /// arr.push(1); + /// arr.push("foo"); + /// assert!(! arr.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Clears the array, removing all values. Keeps the allocated memory for reuse. + pub fn clear(&mut self) { + self.values.clear() + } + + /// Returns a reference to the value at the given index, or `None` if the index is out of + /// bounds. + pub fn get(&self, index: usize) -> Option<&Value> { + self.values.get(index).and_then(Item::as_value) + } + + /// Returns a reference to the value at the given index, or `None` if the index is out of + /// bounds. + pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> { + self.values.get_mut(index).and_then(Item::as_value_mut) + } + + /// Appends a new value to the end of the array, applying default formatting to it. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// ``` + pub fn push>(&mut self, v: V) { + self.value_op(v.into(), true, |items, value| { + items.push(Item::Value(value)) + }) + } + + /// Appends a new, already formatted value to the end of the array. + /// + /// # Examples + /// + /// ```rust + /// let formatted_value = "'literal'".parse::().unwrap(); + /// let mut arr = toml_edit::Array::new(); + /// arr.push_formatted(formatted_value); + /// ``` + pub fn push_formatted(&mut self, v: Value) { + self.values.push(Item::Value(v)); + } + + /// Inserts an element at the given position within the array, applying default formatting to + /// it and shifting all values after it to the right. + /// + /// # Panics + /// + /// Panics if `index > len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// arr.insert(0, "start"); + /// ``` + pub fn insert>(&mut self, index: usize, v: V) { + self.value_op(v.into(), true, |items, value| { + items.insert(index, Item::Value(value)) + }) + } + + /// Inserts an already formatted value at the given position within the array, shifting all + /// values after it to the right. + /// + /// # Panics + /// + /// Panics if `index > len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// let formatted_value = "'start'".parse::().unwrap(); + /// arr.insert_formatted(0, formatted_value); + /// ``` + pub fn insert_formatted(&mut self, index: usize, v: Value) { + self.values.insert(index, Item::Value(v)) + } + + /// Replaces the element at the given position within the array, preserving existing formatting. + /// + /// # Panics + /// + /// Panics if `index >= len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// arr.replace(0, "start"); + /// ``` + pub fn replace>(&mut self, index: usize, v: V) -> Value { + // Read the existing value's decor and preserve it. + let existing_decor = self + .get(index) + .unwrap_or_else(|| panic!("index {} out of bounds (len = {})", index, self.len())) + .decor(); + let mut value = v.into(); + *value.decor_mut() = existing_decor.clone(); + self.replace_formatted(index, value) + } + + /// Replaces the element at the given position within the array with an already formatted value. + /// + /// # Panics + /// + /// Panics if `index >= len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// let formatted_value = "'start'".parse::().unwrap(); + /// arr.replace_formatted(0, formatted_value); + /// ``` + pub fn replace_formatted(&mut self, index: usize, v: Value) -> Value { + match mem::replace(&mut self.values[index], Item::Value(v)) { + Item::Value(old_value) => old_value, + x => panic!("non-value item {:?} in an array", x), + } + } + + /// Removes the value at the given index. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// arr.remove(0); + /// assert_eq!(arr.len(), 1); + /// ``` + pub fn remove(&mut self, index: usize) -> Value { + let removed = self.values.remove(index); + match removed { + Item::Value(v) => v, + x => panic!("non-value item {:?} in an array", x), + } + } + + fn value_op( + &mut self, + v: Value, + decorate: bool, + op: impl FnOnce(&mut Vec, Value) -> T, + ) -> T { + let mut value = v; + if !self.is_empty() && decorate { + value.decorate(" ", ""); + } else if decorate { + value.decorate("", ""); + } + op(&mut self.values, value) + } +} + +impl std::fmt::Display for Array { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + crate::encode::Encode::encode(self, f, None, ("", "")) + } +} + +impl> Extend for Array { + fn extend>(&mut self, iter: T) { + for value in iter { + self.push_formatted(value.into()); + } + } +} + +impl> FromIterator for Array { + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + let v = iter.into_iter().map(|a| Item::Value(a.into())); + Array { + values: v.collect(), + ..Default::default() + } + } +} + +impl IntoIterator for Array { + type Item = Value; + type IntoIter = ArrayIntoIter; + + fn into_iter(self) -> Self::IntoIter { + Box::new( + self.values + .into_iter() + .filter(|v| v.is_value()) + .map(|v| v.into_value().unwrap()), + ) + } +} + +impl<'s> IntoIterator for &'s Array { + type Item = &'s Value; + type IntoIter = ArrayIter<'s>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +fn decorate_array(array: &mut Array) { + for (i, value) in array + .values + .iter_mut() + .filter_map(Item::as_value_mut) + .enumerate() + { + // [value1, value2, value3] + if i == 0 { + value.decorate(DEFAULT_LEADING_VALUE_DECOR.0, DEFAULT_LEADING_VALUE_DECOR.1); + } else { + value.decorate(DEFAULT_VALUE_DECOR.0, DEFAULT_VALUE_DECOR.1); + } + } + // Since everything is now on the same line, remove trailing commas and whitespace. + array.set_trailing_comma(false); + array.set_trailing(""); +} -- cgit v1.2.3