aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBourgond Aries <macocio@gmail.com>2016-03-24 14:18:00 +0100
committerBourgond Aries <macocio@gmail.com>2016-03-24 14:18:00 +0100
commit9b1dc843fcd2158930cc8b9de1bfc9cb8eedf127 (patch)
treedc7dea04d229a39c693c287232ea826185735e3e
parentcf718f7b0e3246c21de96b413f38d002339168da (diff)
downloadmilf-rs-9b1dc843fcd2158930cc8b9de1bfc9cb8eedf127.tar.gz
milf-rs-9b1dc843fcd2158930cc8b9de1bfc9cb8eedf127.zip
Add lookup_mut method for mutable access
Mutable access may sometimes be desired in order to change values in the toml table. This can be used for dynamic configurations which will be easy to modify and store. lookup_mut requires a recursive method due to the borrow checker not allowing to have more than one mutable reference in the same scope.
-rw-r--r--src/lib.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index a5ecb5d..21cdf3e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -44,6 +44,7 @@
use std::collections::BTreeMap;
use std::str::FromStr;
+use std::str::Split;
pub use parser::{Parser, ParserError};
@@ -206,6 +207,67 @@ impl Value {
Some(cur_value)
}
+
+ fn lookup_mut_recurse<'a>(&'a mut self, matches: &mut Split<'a, char>) -> Option<&'a mut Value> {
+ if let Some(key) = matches.next() {
+ match *self {
+ Value::Table(ref mut hm) => {
+ match hm.get_mut(key) {
+ Some(v) => return v.lookup_mut_recurse(matches),
+ None => return None,
+ }
+ },
+ Value::Array(ref mut v) => {
+ match key.parse::<usize>().ok() {
+ Some(idx) if idx < v.len()
+ => return (&mut v[idx]).lookup_mut_recurse(matches),
+ _ => return None,
+ }
+ },
+ _ => return None
+ }
+ }
+ Some(self)
+ }
+
+ /// Lookups for mutable value at specified path.
+ ///
+ /// Uses '.' as a path separator.
+ ///
+ /// Note: arrays have zero-based indexes.
+ ///
+ /// Note: empty path returns self.
+ ///
+ /// ```
+ /// # #![allow(unstable)]
+ /// let toml = r#"
+ /// [test]
+ /// foo = "bar"
+ ///
+ /// [[values]]
+ /// foo = "baz"
+ ///
+ /// [[values]]
+ /// foo = "qux"
+ /// "#;
+ /// let mut value: toml::Value = toml.parse().unwrap();
+ /// {
+ /// let string = value.lookup_mut("test.foo").unwrap();
+ /// assert_eq!(string, &mut toml::Value::String(String::from("bar")));
+ /// *string = toml::Value::String(String::from("foo"));
+ /// }
+ /// let result = value.lookup_mut("test.foo").unwrap();
+ /// assert_eq!(result.as_str().unwrap(), "foo");
+ /// ```
+ pub fn lookup_mut<'a>(&'a mut self, path: &'a str) -> Option<&'a mut Value> {
+ if path.len() == 0 {
+ return Some(self)
+ }
+
+ let mut matches = path.split('.');
+ self.lookup_mut_recurse(&mut matches)
+ }
+
}
impl FromStr for Value {