🐷
RustでHashMapを任意の型にDeserializeする
使いどころがわからないですが、副産物的に知らなかったことを学べたのでメモ程度で置いておきます。隙間時間でRust初めて1ヶ月の初心者なので、書き方におかしい部分などあったらご指摘ください。
概要
- rustで以下の感じの任意のValueを持つHashMapを、ある型に変換したいと思いました。
// HashMap
{
para: "hogehoge",
vec_para: ["hehe1", "hehe2"],
}
// struct
struct MyStruct {
para: String,
vec_para: Vec<String>,
}
ハマったこと
- 任意の値を持つHashMapを作れない
- HashMapを構造体に変換できない
以下どう対処(妥協)したか書いてきます。
対処
1. 任意の値を持つHashMapを作れない
これは悩んだ末、2通り対処を考えました。
-
std::any::Any
を使う -
enum
である程度値の型を限定する
前者だと、serialize/deserialize
のためにserde_traitobjectを使う必要がありました。ただ、その際metatypeに#[feature]
のものがあり、stable版Rustではだめそうだったので止めました。
結局は後者でenumを作って単値(String
)、多値(Vec<String>
)のみを受けることにしました。
2. HashMapを構造体に変換できない
これはserdeとserde_jsonを使えばすんなりできました。
ただしenum
をserialize
するときにStr
とかArr
が表示されないように#[serde(untagged)]
をつける必要がありました。
ここまででできたもの
まとめ
何に使うかわからないですが、以下2点は学びでした。
-
serde
のuntagged
(というかserde
クレートを初めて知った) - HashMapに任意の型持たせるときはenumで持たせる(当然)
Discussion