Hi all.
I'm trying to work with the toml file parser, which from what I understand uses b-trees to structure it's data. While I understand b-trees and how they work, I don't really know how to work with the 'toml' crate.
The experimental code I've written is;
extern crate getopts; // Command line options crate
extern crate toml; // A toml file parser
fn main() {
let toml = r#"
[test]
foo = "bar"
bar = "foo"
[test2]
boolean = true
"#;
let value = toml::Parser::new(toml).parse().unwrap();
println!("1: {:?}\n", value);
println!("2: {:?}\n", value.get("test"));
let table = value.get("test").unwrap();
match table {
foo => println!("3: {:?}", &foo),
}
for obj in value.get("test").into_iter() {
println!("4: {:?}", obj);
}
}
I'm trying to access the foo and bar fields of [test]
I don't purport to be an expert at Rust or TOML, but this is how I have done it in rust-enum-derive:
// A macro to retrieve an str element from a toml::Table
// $t - Table to lookup in
// $a - Where to assign Some(String)
// $v - the name to look for in the toml
macro_rules! get_key_string {
($t:ident, $a:ident, $v:ident) => {
if $t.contains_key(stringify!($v)) {
let $v = $t.get(stringify!($v)).unwrap();
let $v = $v.as_str();
if $v.is_none() {
return Err(Error::new(ErrorKind::Other,
format!("{} wasn't available as str",
stringify!($v))))
}
let $v = $v.unwrap();
$a.$v = Some(String::from($v));
}
}
}
// same as get_key_bool, except for bool instead of str/string
macro_rules! get_key_bool {
($t:ident, $a:ident, $v:ident) => {
if $t.contains_key(stringify!($v)) {
let $v = $t.get(stringify!($v)).unwrap();
let $v = $v.as_bool();
if $v.is_none() {
return Err(Error::new(ErrorKind::Other,
format!("{} wasn't available as bool",
stringify!($v))))
}
$a.$v = $v.unwrap();
}
}
}
fn parse_toml(path: &PathBuf) -> Result<FileArgs>
{
let mut fa = FileArgs::default();
let mut f = try!(File::open(&path));
let mut s = String::new();
try!(f.read_to_string(&mut s));
let table = toml::Parser::new(&s).parse();
if table.is_none() {
return Err(Error::new(ErrorKind::Other,
format!("failed to parse {}", path.display())))
}
let table = table.unwrap();
let rust_enum_derive = table.get("rust-enum-derive");
if rust_enum_derive.is_none() {
return Err(Error::new(ErrorKind::Other,
format!("couldn't find a rust-enum-derive table in {}",
path.display())))
}
let rust_enum_derive = rust_enum_derive.unwrap();
let rust_enum_derive = rust_enum_derive.as_table();
if rust_enum_derive.is_none() {
return Err(Error::new(ErrorKind::Other,
format!("rust-enum-derive wasn't a table")))
}
let rust_enum_derive = rust_enum_derive.unwrap();
get_key_string!(rust_enum_derive, fa, name);
get_key_string!(rust_enum_derive, fa, derive);
get_key_bool!(rust_enum_derive, fa, define);
get_key_bool!(rust_enum_derive, fa, default);
get_key_bool!(rust_enum_derive, fa, display);
get_key_bool!(rust_enum_derive, fa, fromstr);
get_key_bool!(rust_enum_derive, fa, fromprimative);
get_key_bool!(rust_enum_derive, fa, hex);
get_key_bool!(rust_enum_derive, fa, pretty_fmt);
println!("fa = {:?}", fa);
Ok(fa)
}
You shouldn't know how to work with B-trees just to use a BTreeMap, it's just an "associative array" (key to value map). (But b-trees are awsome anyway).