如何将 toml-rs 结果转换为 std::collections::HashMap [英] How can I convert toml-rs result to std::collections::HashMap

查看:27
本文介绍了如何将 toml-rs 结果转换为 std::collections::HashMap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Rust 的新手,正在尝试构建一些简单的东西.我想从 .toml 文件加载数据并使用 rustache 来渲染一些来自它的文本.

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.

Rustache 似乎采用 HashMap 作为其数据源,我确定从查看 toml-rs 文档,我应该能够将其 TableArray 类型转换为 HashMaps 和 Vecs,我怀疑它与Decoder有关,但我想不通.

Rustache appears to take a HashMap as its data source, and I'm sure from looking at the toml-rs docs that I should be able to convert its Table and Array types to HashMaps and Vecs, and I suspect it's got something to do with Decoder, but I can't figure it out.

如果有人能提供一个简短的例子来说明如何做到这一点,我将不胜感激.

If somebody could provide a short example of how to do this I would be very grateful.

推荐答案

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

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]

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

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

在处理嵌套表和数组时存在不幸的克隆 - 这是 rustache 中问题的结果.如果修复了,可以删除clone(),然后应该使闭包move.

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.

这篇关于如何将 toml-rs 结果转换为 std::collections::HashMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆