2015-10-07 66 views
3

我是Rust的新手,嘗試構建簡單的事情。我想從.toml文件加載數據,並使用rustache來渲染一些文本。如何將toml-rs結果轉換爲std :: collections :: HashMap

Rustache似乎採取一個HashMap作爲數據源,我敢肯定,從看toml-rs文檔,我應該能夠將其TableArray類型轉換爲HashMap S和Vec S,我懷疑它有與Decoder有關,但我無法弄清楚。

如果有人可以提供一個簡短的例子來說明如何做到這一點,我將非常感激。

回答

7

如果你的數據結構已經固定的已知深度,那麼所有你需要的僅僅是傳遞一個正確的類型toml::decode()

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

上面的代碼將解析文檔一樣

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

然而,據我所見,rustache提供了一些支持任意嵌套的構建器結構。在這種情況下,您需要將「toml::Value」應用於rustache::HashBuilder。你並不需要使用Decodable這個(雖然你可能可以與一些newtypes) - 你只需要編寫一些簡單的功能:

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

有不幸的克隆處理嵌套表和數組時 - 這是an issue生鏽的後果。如果它是固定的,clone()可以被刪除,然後關閉應該被製作move

+0

先生,你是一個紳士和學者。很好的答案。我在你的債務。 –

+0

不客氣:) –