aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-06-27 13:53:15 -0400
committerAlex Crichton <alex@alexcrichton.com>2014-06-27 13:53:15 -0400
commit9c1806283c5a631e44d1ecca016e217f889319ef (patch)
treed031d75674fff1f99d2bcf7d3751425901599359
parent0f9410a7f0d3473aef2b82f218f8b4e0a44386da (diff)
parent13cc8a9201fd8ed5d80ea57a08104aa79a5e757e (diff)
downloadmilf-rs-9c1806283c5a631e44d1ecca016e217f889319ef.tar.gz
milf-rs-9c1806283c5a631e44d1ecca016e217f889319ef.zip
Merge pull request #1 from vhbit/lookups
Path lookups
-rw-r--r--src/toml.rs105
1 files changed, 103 insertions, 2 deletions
diff --git a/src/toml.rs b/src/toml.rs
index 33be0f8..440da6a 100644
--- a/src/toml.rs
+++ b/src/toml.rs
@@ -34,6 +34,7 @@
//!
//! [1]: https://github.com/mojombo/toml
//! [2]: https://github.com/BurntSushi/toml-test
+//!
#![crate_type = "lib"]
#![feature(macro_rules)]
@@ -54,8 +55,7 @@ pub use serialization::{InvalidMapKeyLocation, InvalidMapKeyType};
mod parser;
mod show;
mod serialization;
-#[cfg(test)] mod test;
-
+#[cfg(test)]mod test;
/// Representation of a TOML value.
#[deriving(PartialEq, Clone)]
#[allow(missing_doc)]
@@ -142,6 +142,58 @@ impl Value {
pub fn as_table<'a>(&'a self) -> Option<&'a Table> {
match *self { Table(ref s) => Some(s), _ => None }
}
+
+ /// Lookups for value at specified path.
+ ///
+ /// Uses '.' as a path separator.
+ ///
+ /// Note: arrays have zero-based indexes.
+ ///
+ /// ```
+ /// let toml = r#"
+ /// [test]
+ /// foo = "bar"
+ ///
+ /// [[values]]
+ /// foo = "baz"
+ ///
+ /// [[values]]
+ /// foo = "qux"
+ /// "#;
+ /// let value: toml::Value = from_str(toml).unwrap();
+ ///
+ /// let foo = value.lookup("test.foo").unwrap();
+ /// assert_eq!(foo.as_str().unwrap(), "bar");
+ ///
+ /// let foo = value.lookup("values.1.foo").unwrap();
+ /// assert_eq!(foo.as_str().unwrap(), "qux");
+ ///
+ /// let no_bar = value.lookup("test.bar");
+ /// assert_eq!(no_bar.is_none(), true);
+ /// ```
+ pub fn lookup<'a>(&'a self, path: &'a str) -> Option<&'a Value> {
+ let mut cur_value = self;
+ for key in path.split('.') {
+ match cur_value {
+ &Table(ref hm) => {
+ match hm.find_equiv(&key) {
+ Some(v) => cur_value = v,
+ _ => return None
+ }
+ },
+ &Array(ref v) => {
+ let idx: Option<uint> = FromStr::from_str(key);
+ match idx {
+ Some(idx) if idx < v.len() => cur_value = v.get(idx),
+ _ => return None
+ }
+ },
+ _ => return None
+ }
+ };
+
+ Some(cur_value)
+ }
}
impl FromStr for Value {
@@ -149,3 +201,52 @@ impl FromStr for Value {
Parser::new(s).parse().map(Table)
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::Value;
+
+ #[test]
+ fn lookup_valid() {
+ let toml = r#"
+ [test]
+ foo = "bar"
+
+ [[values]]
+ foo = "baz"
+
+ [[values]]
+ foo = "qux"
+ "#;
+
+ let value: Value = from_str(toml).unwrap();
+
+ let test_foo = value.lookup("test.foo").unwrap();
+ assert_eq!(test_foo.as_str().unwrap(), "bar");
+
+ let foo1 = value.lookup("values.1.foo").unwrap();
+ assert_eq!(foo1.as_str().unwrap(), "qux");
+
+ let no_bar = value.lookup("test.bar");
+ assert!(no_bar.is_none());
+ }
+
+ #[test]
+ fn lookup_invalid_index() {
+ let toml = r#"
+ [[values]]
+ foo = "baz"
+ "#;
+
+ let value: Value = from_str(toml).unwrap();
+
+ let foo = value.lookup("test.foo");
+ assert!(foo.is_none());
+
+ let foo = value.lookup("values.100.foo");
+ assert!(foo.is_none());
+
+ let foo = value.lookup("values.str.foo");
+ assert!(foo.is_none());
+ }
+}