diff options
Diffstat (limited to 'vendor/toml_edit-0.19.11/src/visit_mut.rs')
-rw-r--r-- | vendor/toml_edit-0.19.11/src/visit_mut.rs | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/vendor/toml_edit-0.19.11/src/visit_mut.rs b/vendor/toml_edit-0.19.11/src/visit_mut.rs new file mode 100644 index 000000000..2c2af9752 --- /dev/null +++ b/vendor/toml_edit-0.19.11/src/visit_mut.rs @@ -0,0 +1,252 @@ +#![allow(missing_docs)] + +//! Document tree traversal to mutate an exclusive borrow of a document tree in place. +//! +//! +//! Each method of the [`VisitMut`] trait is a hook that can be overridden +//! to customize the behavior when mutating the corresponding type of node. +//! By default, every method recursively visits the substructure of the +//! input by invoking the right visitor method of each of its fields. +//! +//! ``` +//! # use toml_edit::{Item, ArrayOfTables, Table, Value}; +//! +//! pub trait VisitMut { +//! /* ... */ +//! +//! fn visit_item_mut(&mut self, i: &mut Item) { +//! visit_item_mut(self, i); +//! } +//! +//! /* ... */ +//! # fn visit_value_mut(&mut self, i: &mut Value); +//! # fn visit_table_mut(&mut self, i: &mut Table); +//! # fn visit_array_of_tables_mut(&mut self, i: &mut ArrayOfTables); +//! } +//! +//! pub fn visit_item_mut<V>(v: &mut V, node: &mut Item) +//! where +//! V: VisitMut + ?Sized, +//! { +//! match node { +//! Item::None => {} +//! Item::Value(value) => v.visit_value_mut(value), +//! Item::Table(table) => v.visit_table_mut(table), +//! Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array), +//! } +//! } +//! ``` +//! +//! The API is modeled after [`syn::visit_mut`](https://docs.rs/syn/1/syn/visit_mut). +//! +//! # Examples +//! +//! This visitor replaces every floating point value with its decimal string representation, to +//! 2 decimal points. +//! +//! ``` +//! # use toml_edit::*; +//! use toml_edit::visit_mut::*; +//! +//! struct FloatToString; +//! +//! impl VisitMut for FloatToString { +//! fn visit_value_mut(&mut self, node: &mut Value) { +//! if let Value::Float(f) = node { +//! // Convert the float to a string. +//! let mut s = Formatted::new(format!("{:.2}", f.value())); +//! // Copy over the formatting. +//! std::mem::swap(s.decor_mut(), f.decor_mut()); +//! *node = Value::String(s); +//! } +//! // Most of the time, you will also need to call the default implementation to recurse +//! // further down the document tree. +//! visit_value_mut(self, node); +//! } +//! } +//! +//! let input = r#" +//! banana = 3.26 +//! table = { apple = 4.5 } +//! "#; +//! +//! let mut document: Document = input.parse().unwrap(); +//! let mut visitor = FloatToString; +//! visitor.visit_document_mut(&mut document); +//! +//! let output = r#" +//! banana = "3.26" +//! table = { apple = "4.50" } +//! "#; +//! +//! assert_eq!(format!("{}", document), output); +//! ``` +//! +//! For a more complex example where the visitor has internal state, see `examples/visit.rs` +//! [on GitHub](https://github.com/ordian/toml_edit/blob/master/examples/visit.rs). + +use crate::{ + Array, ArrayOfTables, Datetime, Document, Formatted, InlineTable, Item, KeyMut, Table, + TableLike, Value, +}; + +/// Document tree traversal to mutate an exclusive borrow of a document tree in-place. +/// +/// See the [module documentation](self) for details. +pub trait VisitMut { + fn visit_document_mut(&mut self, node: &mut Document) { + visit_document_mut(self, node); + } + + fn visit_item_mut(&mut self, node: &mut Item) { + visit_item_mut(self, node); + } + + fn visit_table_mut(&mut self, node: &mut Table) { + visit_table_mut(self, node); + } + + fn visit_inline_table_mut(&mut self, node: &mut InlineTable) { + visit_inline_table_mut(self, node) + } + + /// [`visit_table_mut`](Self::visit_table_mut) and + /// [`visit_inline_table_mut`](Self::visit_inline_table_mut) both recurse into this method. + fn visit_table_like_mut(&mut self, node: &mut dyn TableLike) { + visit_table_like_mut(self, node); + } + + fn visit_table_like_kv_mut(&mut self, key: KeyMut<'_>, node: &mut Item) { + visit_table_like_kv_mut(self, key, node); + } + + fn visit_array_mut(&mut self, node: &mut Array) { + visit_array_mut(self, node); + } + + fn visit_array_of_tables_mut(&mut self, node: &mut ArrayOfTables) { + visit_array_of_tables_mut(self, node); + } + + fn visit_value_mut(&mut self, node: &mut Value) { + visit_value_mut(self, node); + } + + fn visit_boolean_mut(&mut self, node: &mut Formatted<bool>) { + visit_boolean_mut(self, node) + } + + fn visit_datetime_mut(&mut self, node: &mut Formatted<Datetime>) { + visit_datetime_mut(self, node); + } + + fn visit_float_mut(&mut self, node: &mut Formatted<f64>) { + visit_float_mut(self, node) + } + + fn visit_integer_mut(&mut self, node: &mut Formatted<i64>) { + visit_integer_mut(self, node) + } + + fn visit_string_mut(&mut self, node: &mut Formatted<String>) { + visit_string_mut(self, node) + } +} + +pub fn visit_document_mut<V>(v: &mut V, node: &mut Document) +where + V: VisitMut + ?Sized, +{ + v.visit_table_mut(node.as_table_mut()); +} + +pub fn visit_item_mut<V>(v: &mut V, node: &mut Item) +where + V: VisitMut + ?Sized, +{ + match node { + Item::None => {} + Item::Value(value) => v.visit_value_mut(value), + Item::Table(table) => v.visit_table_mut(table), + Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array), + } +} + +pub fn visit_table_mut<V>(v: &mut V, node: &mut Table) +where + V: VisitMut + ?Sized, +{ + v.visit_table_like_mut(node); +} + +pub fn visit_inline_table_mut<V>(v: &mut V, node: &mut InlineTable) +where + V: VisitMut + ?Sized, +{ + v.visit_table_like_mut(node); +} + +pub fn visit_table_like_mut<V>(v: &mut V, node: &mut dyn TableLike) +where + V: VisitMut + ?Sized, +{ + for (key, item) in node.iter_mut() { + v.visit_table_like_kv_mut(key, item); + } +} + +pub fn visit_table_like_kv_mut<V>(v: &mut V, _key: KeyMut<'_>, node: &mut Item) +where + V: VisitMut + ?Sized, +{ + v.visit_item_mut(node) +} + +pub fn visit_array_mut<V>(v: &mut V, node: &mut Array) +where + V: VisitMut + ?Sized, +{ + for value in node.iter_mut() { + v.visit_value_mut(value); + } +} + +pub fn visit_array_of_tables_mut<V>(v: &mut V, node: &mut ArrayOfTables) +where + V: VisitMut + ?Sized, +{ + for table in node.iter_mut() { + v.visit_table_mut(table); + } +} + +pub fn visit_value_mut<V>(v: &mut V, node: &mut Value) +where + V: VisitMut + ?Sized, +{ + match node { + Value::String(s) => v.visit_string_mut(s), + Value::Integer(i) => v.visit_integer_mut(i), + Value::Float(f) => v.visit_float_mut(f), + Value::Boolean(b) => v.visit_boolean_mut(b), + Value::Datetime(dt) => v.visit_datetime_mut(dt), + Value::Array(array) => v.visit_array_mut(array), + Value::InlineTable(table) => v.visit_inline_table_mut(table), + } +} + +macro_rules! empty_visit_mut { + ($name: ident, $t: ty) => { + fn $name<V>(_v: &mut V, _node: &mut $t) + where + V: VisitMut + ?Sized, + { + } + }; +} + +empty_visit_mut!(visit_boolean_mut, Formatted<bool>); +empty_visit_mut!(visit_datetime_mut, Formatted<Datetime>); +empty_visit_mut!(visit_float_mut, Formatted<f64>); +empty_visit_mut!(visit_integer_mut, Formatted<i64>); +empty_visit_mut!(visit_string_mut, Formatted<String>); |