How can I convert toml-rs result to std::collections::HashMap

前端 未结 1 1021
情话喂你
情话喂你 2021-01-13 04:58

I\'m new to Rust and trying to build something simple to get going. I want to load data from a .toml file and use rustache to render out some text from it.

相关标签:
1条回答
  • 2021-01-13 05:34

    If your data structure has fixed known depth, then all you need is just to pass a correct type to toml::decode():

    let value: toml::Value = toml::Value::Table(Parser::new(input).parse().unwrap());
    let data: HashMap<String, Vec<u32>> = toml::decode(value).unwrap();
    

    The code above would parse a document like

    x = [1, 2, 3]
    y = [4, 5, 6]
    

    However, as far as I can see, rustache provides some kind of builder structure which supports arbitrary nesting. In that case you would need to "apply" toml::Value to rustache::HashBuilder. You don't need to use Decodable for this (though you probably can, with some newtypes) - you just need to write a couple of simple functions:

    fn toml_into_hashbuilder<'a>(value: toml::Table, mut hb: rustache::HashBuilder<'a>) -> rustache::HashBuilder<'a> {
        for (k, v) in value {
            match v {
                toml::Value::String(s) => hb.insert_string(k, s),
                toml::Value::Integer(i) => hb.insert_int(k, i),
                toml::Value::Float(f) => hb.insert_float(k, f),
                toml::Value::Boolean(b) => hb.insert_bool(k, b),
                toml::Value::Datetime(s) => hb.insert_string(k, s),
                toml::Value::Array(arr) => hb.insert_vector(k, |vb| toml_into_vecbuilder(arr.clone(), vb)),
                toml::Value::Table(tbl) => hb.insert_hash(k, |hb| toml_into_hashbuilder(tbl.clone(), hb))
            }
        }
        hb
    }
    
    fn toml_into_vecbuilder<'a>(value: toml::Array, mut vb: rustache::VecBuilder<'a>) -> rustache::VecBuilder<'a> {
        for v in value {
            match v {
                toml::Value::String(s) => vb.push_string(s),
                toml::Value::Integer(i) => vb.push_int(i),
                toml::Value::Float(f) => vb.push_float(f),
                toml::Value::Boolean(b) => vb.push_bool(b),
                toml::Value::Datetime(s) => vb.push_string(s),
                toml::Value::Array(arr) => vb.push_vector(|vb| toml_into_vecbuilder(arr.clone(), vb)),
                toml::Value::Table(tbl) => vb.push_hash(|hb| toml_into_hashbuilder(tbl.clone(), hb))
            }
        }
        vb
    }
    
    let value: toml::Table = Parser::new(input).parse().unwrap();
    let hb = toml_into_hashbuilder(value, rustache::HashBuilder::new());
    let result = rustache::render_text(your_template, hb);
    

    There are unfortunate clones when handling nested tables and arrays - this is a consequence of an issue in rustache. If it is fixed, clone() could be removed, and the closures should be made move then.

    0 讨论(0)
提交回复
热议问题