serde_json を使用して json ドキュメントを逆シリアル化しています。文字列(これはjsonドキュメントです)を指定すると、serde_json値(これはjsonタイプを表す列挙型)を返し、オプションを返す関数があります。この値は、必要に応じて他の関数に渡されます。
ただし、値を渡すことは、私が望んでいるものではないことに気付きました。これを行うと、キーが利用できないためです。
私の要点を説明するために、次のような json ドキュメントがあるとします。
{
"root" : {
"regex" : null,
"prefixes" : [ "a_", "b_" ]
}
}
"root" は json オブジェクト、"regex" は json Null、"prefixes" は json 配列です。
ここで、json 型の Value は、json 型を表す識別子を持つ列挙型です。たとえば、上記の例では Object、Null、Array です。
serde_json クレートは std::collections::BTreeMap を使用して json ドキュメント内のノードを表し、String 型は json キーを表します (上記では、これらは「ルート」、「正規表現」、および「プレフィックス」になります。 Values への参照だけでは部分的にしか役に立ちません。キーにもアクセスできるように、代わりに BTreeMap を渡す必要があります。
したがって、これは私が書き直そうとしている次の関数です。
fn get_json_content(content_s : &str) -> Option<Value> {
// instead of returning a value, we need to return a BTreeMap, so we can get the
// key and the value.
println!("===>>> json_content obtained: {}", content_s);
match serde_json::from_str(content_s) { // -> Result<Value>
Ok(some_value) => Some(some_value),
Err(_) => None
}
}
そのため、関数を書き直し始めましたが、「この値の型は、このコンテキストで既知である必要があります」というエラーに直面しました。
fn get_json_content_as_btreemap<'a>(content_s : &str) -> Option<&'a BTreeMap<String, Value>> {
match serde_json::from_str(content_s) { // -> Result<Value>
Ok(some) => {
// I expect the type of key_value_pair to be BTreeMap<String, Value>>
// (but I may be wrong!)
let key_value_pair = some.as_object().unwrap(); // Error here
},
Err(_) => None
}
}
このようなスタックオーバーフローに関する他の質問を見つけました: この値のタイプは、このコンテキストで既知である必要があります
これをヘルパーとして使用して、次のように型を挿入しようとしました:
let key_value_pair = some.as_object::<BTreeMap<_, _>>().unwrap();
これは問題を解決しません。また、他の同様のバリエーションを試してみましたが、役に立ちませんでした。では、どうすればこれを修正できますか?
編集:
このアプリには次のような別の機能があります。
fn get_root_value<'a>(json_documemt : &'a Value) -> Result<&'a Value, JsonErrorCode> {
if json_documemt.is_object() {
for (k, v) in json_documemt.as_object().unwrap().iter() {
if k == "root" {
println!("found root: {}", k);
return Ok(v)
}
}
return Err(JsonErrorCode::Custom("Failed to find root node".to_string()))
}
Err(JsonErrorCode::Custom("Not an object".to_string()))
}
...そしてこれはうまくいきます。ここでは、as_object() を呼び出して、キーと値をタプル ペアとして取得できることがわかります。as_object があるケースでは機能しているのに、別のケースでは機能していない理由がわかりません。BTreeMap を取り出して、これを借用アイテムとして渡したいと思います。