summaryrefslogtreecommitdiffstats
path: root/vendor/toml_edit/src/item.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/toml_edit/src/item.rs
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/toml_edit/src/item.rs')
-rw-r--r--vendor/toml_edit/src/item.rs381
1 files changed, 381 insertions, 0 deletions
diff --git a/vendor/toml_edit/src/item.rs b/vendor/toml_edit/src/item.rs
new file mode 100644
index 000000000..48a1a3566
--- /dev/null
+++ b/vendor/toml_edit/src/item.rs
@@ -0,0 +1,381 @@
+use std::str::FromStr;
+
+use toml_datetime::*;
+
+use crate::array_of_tables::ArrayOfTables;
+use crate::table::TableLike;
+use crate::{Array, InlineTable, Table, Value};
+
+/// Type representing either a value, a table, an array of tables, or none.
+#[derive(Debug, Clone)]
+pub enum Item {
+ /// Type representing none.
+ None,
+ /// Type representing value.
+ Value(Value),
+ /// Type representing table.
+ Table(Table),
+ /// Type representing array of tables.
+ ArrayOfTables(ArrayOfTables),
+}
+
+impl Item {
+ /// Sets `self` to the given item iff `self` is none and
+ /// returns a mutable reference to `self`.
+ pub fn or_insert(&mut self, item: Item) -> &mut Item {
+ if self.is_none() {
+ *self = item
+ }
+ self
+ }
+}
+
+// TODO: This should be generated by macro or derive
+/// Downcasting
+impl Item {
+ /// Text description of value type
+ pub fn type_name(&self) -> &'static str {
+ match self {
+ Item::None => "none",
+ Item::Value(v) => v.type_name(),
+ Item::Table(..) => "table",
+ Item::ArrayOfTables(..) => "array of tables",
+ }
+ }
+
+ /// Index into a TOML array or map. A string index can be used to access a
+ /// value in a map, and a usize index can be used to access an element of an
+ /// array.
+ ///
+ /// Returns `None` if:
+ /// - The type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is an array or a
+ /// number.
+ /// - The given key does not exist in the map
+ /// or the given index is not within the bounds of the array.
+ pub fn get<I: crate::index::Index>(&self, index: I) -> Option<&Item> {
+ index.index(self)
+ }
+
+ /// Mutably index into a TOML array or map. A string index can be used to
+ /// access a value in a map, and a usize index can be used to access an
+ /// element of an array.
+ ///
+ /// Returns `None` if:
+ /// - The type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is an array or a
+ /// number.
+ /// - The given key does not exist in the map
+ /// or the given index is not within the bounds of the array.
+ pub fn get_mut<I: crate::index::Index>(&mut self, index: I) -> Option<&mut Item> {
+ index.index_mut(self)
+ }
+
+ /// Casts `self` to value.
+ pub fn as_value(&self) -> Option<&Value> {
+ match *self {
+ Item::Value(ref v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Casts `self` to table.
+ pub fn as_table(&self) -> Option<&Table> {
+ match *self {
+ Item::Table(ref t) => Some(t),
+ _ => None,
+ }
+ }
+ /// Casts `self` to array of tables.
+ pub fn as_array_of_tables(&self) -> Option<&ArrayOfTables> {
+ match *self {
+ Item::ArrayOfTables(ref a) => Some(a),
+ _ => None,
+ }
+ }
+ /// Casts `self` to mutable value.
+ pub fn as_value_mut(&mut self) -> Option<&mut Value> {
+ match *self {
+ Item::Value(ref mut v) => Some(v),
+ _ => None,
+ }
+ }
+ /// Casts `self` to mutable table.
+ pub fn as_table_mut(&mut self) -> Option<&mut Table> {
+ match *self {
+ Item::Table(ref mut t) => Some(t),
+ _ => None,
+ }
+ }
+ /// Casts `self` to mutable array of tables.
+ pub fn as_array_of_tables_mut(&mut self) -> Option<&mut ArrayOfTables> {
+ match *self {
+ Item::ArrayOfTables(ref mut a) => Some(a),
+ _ => None,
+ }
+ }
+ /// Casts `self` to value.
+ pub fn into_value(self) -> Result<Value, Self> {
+ match self {
+ Item::None => Err(self),
+ Item::Value(v) => Ok(v),
+ Item::Table(v) => {
+ let v = v.into_inline_table();
+ Ok(Value::InlineTable(v))
+ }
+ Item::ArrayOfTables(v) => {
+ let v = v.into_array();
+ Ok(Value::Array(v))
+ }
+ }
+ }
+ /// In-place convert to a value
+ pub fn make_value(&mut self) {
+ let other = std::mem::take(self);
+ let other = other.into_value().map(Item::Value).unwrap_or(Item::None);
+ *self = other;
+ }
+ /// Casts `self` to table.
+ pub fn into_table(self) -> Result<Table, Self> {
+ match self {
+ Item::Table(t) => Ok(t),
+ Item::Value(Value::InlineTable(t)) => Ok(t.into_table()),
+ _ => Err(self),
+ }
+ }
+ /// Casts `self` to array of tables.
+ pub fn into_array_of_tables(self) -> Result<ArrayOfTables, Self> {
+ match self {
+ Item::ArrayOfTables(a) => Ok(a),
+ Item::Value(Value::Array(a)) => {
+ if a.is_empty() {
+ Err(Item::Value(Value::Array(a)))
+ } else if a.iter().all(|v| v.is_inline_table()) {
+ let mut aot = ArrayOfTables::new();
+ aot.values = a.values;
+ for value in aot.values.iter_mut() {
+ value.make_item();
+ }
+ Ok(aot)
+ } else {
+ Err(Item::Value(Value::Array(a)))
+ }
+ }
+ _ => Err(self),
+ }
+ }
+ // Starting private because the name is unclear
+ pub(crate) fn make_item(&mut self) {
+ let other = std::mem::take(self);
+ let other = match other.into_table().map(crate::Item::Table) {
+ Ok(i) => i,
+ Err(i) => i,
+ };
+ let other = match other.into_array_of_tables().map(crate::Item::ArrayOfTables) {
+ Ok(i) => i,
+ Err(i) => i,
+ };
+ *self = other;
+ }
+ /// Returns true iff `self` is a value.
+ pub fn is_value(&self) -> bool {
+ self.as_value().is_some()
+ }
+ /// Returns true iff `self` is a table.
+ pub fn is_table(&self) -> bool {
+ self.as_table().is_some()
+ }
+ /// Returns true iff `self` is an array of tables.
+ pub fn is_array_of_tables(&self) -> bool {
+ self.as_array_of_tables().is_some()
+ }
+ /// Returns true iff `self` is `None`.
+ pub fn is_none(&self) -> bool {
+ matches!(*self, Item::None)
+ }
+
+ // Duplicate Value downcasting API
+
+ /// Casts `self` to integer.
+ pub fn as_integer(&self) -> Option<i64> {
+ self.as_value().and_then(Value::as_integer)
+ }
+
+ /// Returns true iff `self` is an integer.
+ pub fn is_integer(&self) -> bool {
+ self.as_integer().is_some()
+ }
+
+ /// Casts `self` to float.
+ pub fn as_float(&self) -> Option<f64> {
+ self.as_value().and_then(Value::as_float)
+ }
+
+ /// Returns true iff `self` is a float.
+ pub fn is_float(&self) -> bool {
+ self.as_float().is_some()
+ }
+
+ /// Casts `self` to boolean.
+ pub fn as_bool(&self) -> Option<bool> {
+ self.as_value().and_then(Value::as_bool)
+ }
+
+ /// Returns true iff `self` is a boolean.
+ pub fn is_bool(&self) -> bool {
+ self.as_bool().is_some()
+ }
+
+ /// Casts `self` to str.
+ pub fn as_str(&self) -> Option<&str> {
+ self.as_value().and_then(Value::as_str)
+ }
+
+ /// Returns true iff `self` is a string.
+ pub fn is_str(&self) -> bool {
+ self.as_str().is_some()
+ }
+
+ /// Casts `self` to date-time.
+ pub fn as_datetime(&self) -> Option<&Datetime> {
+ self.as_value().and_then(Value::as_datetime)
+ }
+
+ /// Returns true iff `self` is a date-time.
+ pub fn is_datetime(&self) -> bool {
+ self.as_datetime().is_some()
+ }
+
+ /// Casts `self` to array.
+ pub fn as_array(&self) -> Option<&Array> {
+ self.as_value().and_then(Value::as_array)
+ }
+
+ /// Casts `self` to mutable array.
+ pub fn as_array_mut(&mut self) -> Option<&mut Array> {
+ self.as_value_mut().and_then(Value::as_array_mut)
+ }
+
+ /// Returns true iff `self` is an array.
+ pub fn is_array(&self) -> bool {
+ self.as_array().is_some()
+ }
+
+ /// Casts `self` to inline table.
+ pub fn as_inline_table(&self) -> Option<&InlineTable> {
+ self.as_value().and_then(Value::as_inline_table)
+ }
+
+ /// Casts `self` to mutable inline table.
+ pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> {
+ self.as_value_mut().and_then(Value::as_inline_table_mut)
+ }
+
+ /// Returns true iff `self` is an inline table.
+ pub fn is_inline_table(&self) -> bool {
+ self.as_inline_table().is_some()
+ }
+
+ /// Casts `self` to either a table or an inline table.
+ pub fn as_table_like(&self) -> Option<&dyn TableLike> {
+ self.as_table()
+ .map(|t| t as &dyn TableLike)
+ .or_else(|| self.as_inline_table().map(|t| t as &dyn TableLike))
+ }
+
+ /// Casts `self` to either a table or an inline table.
+ pub fn as_table_like_mut(&mut self) -> Option<&mut dyn TableLike> {
+ match self {
+ Item::Table(t) => Some(t as &mut dyn TableLike),
+ Item::Value(Value::InlineTable(t)) => Some(t as &mut dyn TableLike),
+ _ => None,
+ }
+ }
+
+ /// Returns true iff `self` is either a table, or an inline table.
+ pub fn is_table_like(&self) -> bool {
+ self.as_table_like().is_some()
+ }
+
+ /// Returns the location within the original document
+ pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
+ match self {
+ Item::None => None,
+ Item::Value(v) => v.span(),
+ Item::Table(v) => v.span(),
+ Item::ArrayOfTables(v) => v.span(),
+ }
+ }
+
+ pub(crate) fn despan(&mut self, input: &str) {
+ match self {
+ Item::None => {}
+ Item::Value(v) => v.despan(input),
+ Item::Table(v) => v.despan(input),
+ Item::ArrayOfTables(v) => v.despan(input),
+ }
+ }
+}
+
+impl Default for Item {
+ fn default() -> Self {
+ Item::None
+ }
+}
+
+impl FromStr for Item {
+ type Err = crate::TomlError;
+
+ /// Parses a value from a &str
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let value = s.parse::<Value>()?;
+ Ok(Item::Value(value))
+ }
+}
+
+impl std::fmt::Display for Item {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match &self {
+ Item::None => Ok(()),
+ Item::Value(v) => v.fmt(f),
+ Item::Table(v) => v.fmt(f),
+ Item::ArrayOfTables(v) => v.fmt(f),
+ }
+ }
+}
+
+/// Returns a formatted value.
+///
+/// Since formatting is part of a `Value`, the right hand side of the
+/// assignment needs to be decorated with a space before the value.
+/// The `value` function does just that.
+///
+/// # Examples
+/// ```rust
+/// # use snapbox::assert_eq;
+/// # use toml_edit::*;
+/// let mut table = Table::default();
+/// let mut array = Array::default();
+/// array.push("hello");
+/// array.push("\\, world"); // \ is only allowed in a literal string
+/// table["key1"] = value("value1");
+/// table["key2"] = value(42);
+/// table["key3"] = value(array);
+/// assert_eq(table.to_string(),
+/// r#"key1 = "value1"
+/// key2 = 42
+/// key3 = ["hello", '\, world']
+/// "#);
+/// ```
+pub fn value<V: Into<Value>>(v: V) -> Item {
+ Item::Value(v.into())
+}
+
+/// Returns an empty table.
+pub fn table() -> Item {
+ Item::Table(Table::new())
+}
+
+/// Returns an empty array of tables.
+pub fn array() -> Item {
+ Item::ArrayOfTables(ArrayOfTables::new())
+}