rust Serde使用关键字标签反序列化

dl5txlt9  于 2023-01-05  发布在  其他
关注(0)|答案(1)|浏览(208)

以下是我使用serde::反序列化的代码;

#[derive(Debug, Deserialize)]
struct OuterStruct{  
  name: String,
  value: i64,
  inner: Wrapper,
}
#[derive(Debug, Deserialize)]
struct structA{
  #[serde(rename = "type")]
  ttype: String
  field: String
}
#[derive(Debug, Deserialize)]
struct structB{
  #[serde(rename = "type")]
  ttype: String
  field: String
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
enum Wrapper{
  typea(structA),
  typeb(structB),
}

在我的理解中,#[serde(tag = "type")]将使用字段类型来决定使用哪个枚举变量进行反序列化,但是我会得到类似missing field ``type`` at line 1 column 177"的错误
我还尝试了#[serde(tag ="ttype")],这是原始字段名,但仍然没有成功
我当前的解决方法是:就像答案中提到的cafce25一样,从结构体中删除ttype

impl Wrapper{
  fn get_type(&self)->String{
    match &self{
      Wrapper::typea(_)=>"typea".to_string(),
      Wrapper::typeb(_)=>"typeb".to_string(),
    }
  }
}

我有办法把type字段保留在结构体中吗?

chy5wohz

chy5wohz1#

#[serde(tag = "type")]的要点是在结构体上没有冗余字段,因为信息是在类型中编码的,只需从结构体中删除ttype字段。

use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct StructA {
    field: String,
}
#[derive(Debug, Deserialize)]
struct StructB {
    field: String,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
enum Wrapper {
    TypeA(StructA),
    TypeB(StructB),
}

相关问题