20

Serde を使用して、github の Bowserinatorから化学元素の JSON ファイルをデシリアライズしたいと考えています。このために、必要なすべてのフィールドを含む構造を作成し、必要なマクロを派生させました。

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
    name: String,
    appearance: String,
    atomic_mass: f64,
    boil: f64, 
    category: String,
    #[serde(default)]
    color: String,
    density: f64,
    discovered_by: String,
    melt: f64, 
    #[serde(default)]
    molar_heat: f64,
    named_by: String,
    number: String,
    period: u32,
    phase: String,
    source: String,
    spectral_img: String,
    summary: String,
    symbol: String,
    xpos: u32,
    ypos: u32,
}

これは、「null」値を含むフィールドに到達するまでは正常に機能します。たとえば"color": null,、ヘリウムのフィールドの場合。

表示されるエラー メッセージは{ code: Message("invalid type: unit value, expected a string"), line: 8, column: 17 }、このフィールドに関するものです。

#[serde(default)]マクロで実験しました。ただし、これは値がある場合ではなく、JSON ファイルにフィールドがない場合にのみ機能しnullます。

Visitor Trait をプログラムすることを避けて、標準のマクロでデシリアライズを行うのが好きです。私が見逃しているトリックはありますか?

4

3 に答える 3

3

hereのコードに基づいて、存在する場合にデフォルト値を逆シリアル化する必要がある場合null

// Omitting other derives, for brevity 
#[derive(Deserialize)]
struct Foo {
   #[serde(deserialize_with = "deserialize_null_default")]
   value: String, 
}

fn deserialize_null_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
    T: Default + Deserialize<'de>,
    D: Deserializer<'de>,
{
    let opt = Option::deserialize(deserializer)?;
    Ok(opt.unwrap_or_default())
}

完全な例を含む遊び場リンク。これは と にも機能しVecますHashMap

于 2021-01-13T15:39:48.910 に答える