[Solved] Using B-Trees (and the toml crate)


#1

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]


#2

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)
}

#3

Hey thanks. That gave me a few good ideas.
Also very nice to see good macros being used :slightly_smiling:


#4

What does that profile photo mean?


#5

Er, what photo?


#6

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).