如何使用标签从严格的 serde_json 反序列化访问字段

时间:2021-04-22 15:36:48

标签: rust

我在 Some(Address{...}) 的地址字段中得到 data,这是预期的。我可以从调试打印输出中看到它。

但是&data.Address = &data.Address.unwrap();

给我静态错误说:“没有字段 Address on type Profile”

let mut data:Profile = serde_json::from_str(json_string).unwrap();
&data.Address = &data.Address.unwrap();

#[derive(Deserialize, Debug, Serialize)]
#[serde(tag = "m_tag")]
pub enum Profile {
   Data{
    #[serde(rename="FirstName")] // to comply with Rust coding standards
    first_name:String,
    LastName: String,
    Age: u32,
    Address:  Option<Address>,
    PhoneNumbers: Vec<String>
   },
   Data2{
    #[serde(rename="FirstName")] // to comply with Rust coding standards
    first_name:String,
    LastName: String,
    Age: u32,
   },

}

#[derive(Serialize, Deserialize)]
struct Address {
    Street: String,
    City: String,
    Country: String
}

更新: Q1) 我可以解开这个值,但是我想更新 &data.Address 给它。 但我又回到了原来的问题,其中 &data 是 Profile 类型并且没有 Address 字段。

 match &data {
        Profile::Data {
            first_name,
            LastName,
            Age,
            Address,
            PhoneNumbers,
        } => data.Address =  &Address.as_ref().unwrap(),
        Profile::Data2 {
           first_name,
           LastName,
           Age,
        } => println!("ok"),
    }

1 个答案:

答案 0 :(得分:0)

编辑:

如果字段重叠,则无需创建 Enum。最好将不能保证存在的字段声明为可选字段:

#[derive(Deserialize, Debug, Serialize)]
struct Profile {
  #[serde(rename="FirstName")]
  first_name:String,
  LastName: String,
  Age: u32,
  Address:  Option<Address>,
  PhoneNumbers: Option<Vec<String>>
};

所以现在可以保证类型 Profile 有一个 Address 字段:

let data:Profile = serde_json::from_str(json_string).unwrap();

println!("{:?}", data.Address);

这是在 Rust Playground 中工作的代码示例。