【问题标题】:Deserializing key and value lists as struct from JSON using serde?使用serde将键和值列表反序列化为JSON的结构?
【发布时间】:2017-11-21 04:48:03
【问题描述】:

我有这样的 JSON:

{
    "fieldNames": ["MyInt", "MyFloat", "MyString"],
    "fieldValues": [5, 10.0, "hello"],
}

我想反序列化成这样的结构:

#[derive(Deserialize)]
struct MyStruct {
    my_int: u64,
    my_float: f64,
    my_string: String,
}

有没有办法用 serde 做到这一点?理想情况下,我想要这样的东西:

#[serde(keys="fieldNames", values="fieldValues")]

【问题讨论】:

    标签: json rust serde


    【解决方案1】:

    这样的事情可能会奏效。这是使用 deserialize_with 函数,可以从包含此函数的任何结构调用。


    #[macro_use]
    extern crate serde_derive;
    
    extern crate serde;
    extern crate serde_json;
    
    use serde::de::{self, Deserialize, DeserializeOwned, Deserializer};
    use serde_json::Value;
    
    #[derive(Deserialize, Debug)]
    struct Spease(#[serde(deserialize_with = "names_values")] MyStruct);
    
    #[derive(Deserialize, Debug)]
    #[serde(rename_all = "PascalCase")]
    struct MyStruct {
        my_int: u64,
        my_float: f64,
        my_string: String,
    }
    
    fn names_values<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where
        T: DeserializeOwned,
        D: Deserializer<'de>
    {
        #[derive(Deserialize)]
        struct Helper {
            #[serde(rename = "fieldNames")]
            names: Vec<String>,
            #[serde(rename = "fieldValues")]
            values: Vec<Value>,
        }
    
        // Deserialize a Vec<String> and Vec<Value>.
        let nv = Helper::deserialize(deserializer)?;
    
        // Zip them together into a map.
        let pairs = Value::Object(nv.names.into_iter().zip(nv.values).collect());
    
        // Deserialize the output type T.
        T::deserialize(pairs).map_err(de::Error::custom)
    }
    
    fn main() {
        let j = r#"{
                     "fieldNames": ["MyInt", "MyFloat", "MyString"],
                     "fieldValues": [5, 10.0, "hello"]
                   }"#;
    
        println!("{:?}", serde_json::from_str::<Spease>(j).unwrap());
    }
    

    【讨论】:

    • 这很棒。我很好奇你为什么选择使用 Owned/String/Value?这是更高效,还是可以通过更多工作进行更多优化? (我尝试用 &str 替换它并遇到错误,随后退出更改)
    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多