Rust 将 JSON 反序列化为自定义 HashMap<String, google_firestore1::Value>

新生锈

我刚开始使用 Rust,在反序列化方面遇到了一些麻烦。

我实际上是在尝试使用以下板条箱google_firestore1 中的ProjectDatabaseDocumentCreateDocumentCall函数我想填充struct的字段结构文档很清楚,它期望 a作为值。fieldsDocumentHashMap<String, google_firestore1::Value>

问题是,如何将 JSON 字符串反序列化为HashMap<String, google_firestore1::Value>

这是我暂时写的代码:

extern crate google_firestore1 as firestore1;

use google_firestore1::Document;
use std::collections::HashMap;
use serde_json;

pub fn go() {

  let _my_doc = Document::default();

  let test = "{\"test\":\"test\", \"myarray\": [1]}";

  // Working perfectly fine
  let _working: HashMap<String, serde_json::Value> = serde_json::from_str(test).unwrap();

  // Not working
  let _not_working: HashMap<String, firestore1::Value> = serde_json::from_str(test).unwrap();

  // Later I want to do the following
  // _my_doc.fields = _not_working
}

显然这不起作用,它会因以下错误而崩溃。

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"test\", expected struct Value", line: 1, column: 14)', src/firestore.rs:17:85
stack backtrace:

当然,我注意到它serde_json::Valuefirestore1::ValueStruct 是不一样的。但是我查看了源代码,似乎firestore1::Value正在实现 Deserialize 特性。

那么为什么它不起作用呢?在这种情况下,我需要遍历第一HashMap和反序列化serde_json::Valuefirestore1::Value一遍吗?有没有更干净的方法来做我想做的事?

谢谢你的回答!

迈克尔·安德森

的定义firestore1::Value是:

/// A message that can hold any of the supported value types.
/// 
/// This type is not used in any activity, and only used as *part* of another schema.
/// 
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct Value {
    /// A bytes value.
    /// 
    /// Must not exceed 1 MiB - 89 bytes.
    /// Only the first 1,500 bytes are considered by queries.
    #[serde(rename="bytesValue")]
    pub bytes_value: Option<String>,
    /// A timestamp value.
    /// 
    /// Precise only to microseconds. When stored, any additional precision is
    /// rounded down.
    #[serde(rename="timestampValue")]
    pub timestamp_value: Option<String>,

    ...

}

这意味着 a 的每个条目都firestore1::Value必须是一个对象。怀疑实际上只会设置一个字段,对应于值的实际类型(因为它们都是可选的)。

所以你的 json 需要是这样的:

let test = r#"{
  "test":{"stringValue":"test"},
  "myarray": {
     "arrayValue":{"values":[{"integerValue":1}]}
  }
}"#;

这是非常丑陋的,所以如果你做了很多自己的JSON到公司的FireStore交谈,我可能会从写一些助手转换serde_json::Valuefirestore1::Value

它可能看起来像这样:

fn my_firestore_from_json(v:serde_json::Value) -> firestore1::Value {
  match v {
    serde_json::Value::Null => firestore::Value {
      // I don't know why this is a Option<String>
      null_value: Some("".to_string),
      ..Default::default(),
    },
    serde_json::Value::Bool(b) => firestore::Value {
      bool_value: Some(b),
      ..Default::default(),
    },
    // Implement this
    serde_json::Value::Number(n) => my_firestore_number(n),
    serde_json::Value::String(s) => firestore::Value {
      string_value: Some(s),
      ..Default::default(),
    },
    serde_json::Value::Array(v) => firestore::Value {
      array_value:
        Some(firestore1::ArrayValue{
            values:v.into_iter().map(my_firestore_from_json)
        }),
      ..Default::default(),
    },
    // Implement this
    serde_json::Value::Object(d) => my_firststore_object(/* something */) 
  }
}

如果From<T>for有各种实现,这会更整洁一些firestore1::Value,但是使用 的实现Default使得这不会太难看。

还值得注意的是,并不是所有的 firebase 类型都在这里创建,因为 serde_json 中表达的类型与 firebase 支持的类型不同。

无论如何,这允许您通过执行以下操作来使用您的 JSON:

let test = "{\"test\":\"test\", \"myarray\": [1]}";
let working: HashMap<String, serde_json::Value> = serde_json::from_str(test).unwrap();
let value_map: HashMap<String, firestore1::Value> = working.iter().map(|(k,v)| (k, my_firestore_from_json(v)).collect();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将JSON.net自定义反序列化为Dictionary <string,string>

Rust:将JSON数组反序列化为一个非常简单的自定义表

无法使用Gson将JSON反序列化为HashMAp <String,POJO>

Newtonsoft.Json - 将 JSON 反序列化为自定义 JObject

使用Objective-C将JSON反序列化为自定义对象

在 Ruby 中不使用 OpenStruct 将 JSON 反序列化为自定义对象

无法将 json 反序列化为 rust 结构

将JSON反序列化为Dictionary <string,List <string >>

将列表<string>从Json反序列化为列表<object>

无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型需要JSON数组(例如[1,2,3])才能正确反序列化

JSON 未反序列化为自定义类

在 jackson 的帮助下将 JSON 数组部分反序列化为 HashMap

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“System.Collections.Generic.List`1”

使用自定义ContractResolver,当将空JSON属性反序列化为值类型成员时,如何设置默认值而不是null?

将包含JodaTime对象的自定义对象序列化为JSON

使用自定义格式将类对象序列化为 JSON

如何将Json反序列化为Dictionary <String,List <String >>

无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型'Value []',因为该类型需要JSON数组(例如[1,2,3])

将[String:Any]序列化为JSON

将JSON反序列化为子类

将 Json 反序列化为对象

JSON .NET - 注释将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1

JSON.Net-无法将当前json对象(例如{“ name”:“ value”})反序列化为类型'system.collections.generic.list`1

尝试在Spring-boot中使用Jackson将JSON数组反序列化为Java String

如何使用Jackson将JSON反序列化为Map <String,Object>成员变量?

C#-将嵌套的json反序列化为嵌套的Dictionary <string,object>

使用Jackson将JSON字符串或对象反序列化为String字段

如何仅使用动态将 JSON 反序列化为简单的 Dictionary<string,object> 到 datagridview?

无法将输入json反序列化为MVC-API中的list <string>