如何将toml-rs结果转换为std :: collections :: HashMap

Mar*_*dle 5 rust

我是Rust的新手,并试图构建一些简单易用的东西.我想从.toml文件加载数据并使用rustache从中渲染出一些文本.

Rustache似乎将HashMap作为其数据源,我确信通过查看toml-rs文档,我应该能够将其TableArray类型转换为HashMaps和Vecs,并且我怀疑它与某些事情有关Decoder,但是我无法弄清楚.

如果有人可以提供一个如何做到这一点的简短例子,我将非常感激.

Vla*_*eev 8

如果您的数据结构具有固定的已知深度,那么您只需要将正确的类型传递给toml::decode():

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

上面的代码会解析像这样的文档

x = [1, 2, 3]
y = [4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

但是,据我所知,rustache提供了某种支持任意嵌套的构建器结构.在这种情况下,你需要"申请" toml::Valuerustache::HashBuilder.你不需要使用Decodable它(虽然你可能可以使用一些新类型) - 你只需要编写几个简单的函数:

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);
Run Code Online (Sandbox Code Playgroud)

处理嵌套表和数组时存在不幸的克隆 - 这是生锈问题的结果.如果它是固定的,clone()可以移除,然后应该关闭move.

  • 先生,您是一位绅士,一位学者。很好的答案。我欠你的情。 (2认同)