2016-08-25 6 views
2

複数のタイプを含むJSONオブジェクトを作成したいと思います。ここ構造です:Rust HashMapを作成するにはどうすればいいですか?値は複数のタイプのうちの1つになりますか?

{ 
    "key1": "value", 
    "key2": ["val", "val", "val"] 
    "key3": { "keyX": 12 } 
} 

は、どのように私はすべてのこれらのタイプを受け入れるHashMapを作ることができますか?

私はこれをしようとしている:

let item = HashMap::new(); 
item.insert("key1", someString); //type is &str 
item.insert("key2", someVecOfStrings); //type is Vec<String> 
item.insert("key3", someOtherHashMap); //Type is HashMap<&str, u32> 

let response = json::encode(&item).unwrap(); 

を私はハッシュマップが十分な型情報を持っていないことを知っているが、私は、私はそれを動作させることが可能かどうかはわかりません。私はitemに明示的なタイプを設定しようとしましたが、これはHashMap<&str, Encodable>でしたが、もう一つのエラーです。これを行う正しい方法は何ですか?

答えて

7

HashMapに値として列挙型を使用する必要があります。それ列挙型は、それぞれの可能なタイプ(ブール値、数値、文字列、リスト、地図...)と各バリアントのための適切なタイプの関連する値のバリアントを持っている必要があります:

enum JsonValue<'a> { 
    String(&'a str), 
    VecOfString(Vec<String>), 
    AnotherHashMap(HashMap<&'a str, u32>), 
} 

幸い、すでにan implementation of a JSON value typeがあり、 serde木枠に構築されているserde_json木枠の一部。ここで

あなたはserde_jsonのクレートを使用した場合、あなたのコードがどのように見えるかです:ここでは

extern crate serde_json; 

use serde_json::{Value, Map, Number}; 

fn main() { 
    let mut inner_map = Map::new(); 
    inner_map.insert("x".to_string(), Value::Number(Number::from(10u64))); 
    inner_map.insert("y".to_string(), Value::Number(Number::from(20u64))); 

    let mut map = Map::new(); 
    map.insert("key1".to_string(), Value::String("test".to_string())); 
    map.insert(
     "key2".to_string(), 
     Value::Array(vec![ 
      Value::String("a".to_string()), 
      Value::String("b".to_string()), 
     ]), 
    ); 
    map.insert("key3".to_string(), Value::Object(inner_map)); 

    println!("{}", serde_json::to_string(&map).unwrap()); 
    // => {"key1":"test","key2":["a","b"],"key3":{"x":10,"y":20}} 
} 
+0

私は質問に掲載した例をどのようにするかの例を教えてください。また、列挙型を使用する以外の方法はありませんか?私はちょうど始まったばかりなので、他の言語と比較して、過剰なもののように思えます。 – Majster

+0

[この箱](https://github.com/maciejhirsz/json-rust)では、JSONを簡単に書くこともできます。 – squiguy

+0

例を追加しました。なぜあなたはそれが過度だと思いますか?これは、錆びたenum(タグ付きの共用体)のかなり単純な使い方です。 –

2

はあなたに、よりおいしいかもしれ別のアプローチです。 serde_json crateは、JSONリテラルからオブジェクトを構築する手段を提供します。あなたの例は次のようになります:

#[macro_use] 
extern crate serde_json; 

fn main() { 
    let item = json!({ 
     "key1": "value", 
     "key2": ["val", "val", "val"], 
     "key3": { "keyX": 12 } 
    }); 

    let response = serde_json::to_string(&item).unwrap(); 
} 
関連する問題