You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现枚举变体与JSON null双向序列化且无需自定义反序列化函数

将JSON的null反序列化为单元式枚举变体(无需自定义反序列化函数)

已实现将单元式枚举变体Action::Delete序列化为JSON的null,现需无需编写专用反序列化函数,直接将JSON中的null反序列化为Action::Delete,同时保留Action::Create对数组格式Entry的正常反序列化能力。

解决方案

通过给Delete变体添加#[serde(deserialize_as = "Option<()>")]属性,配合枚举的#[serde(untagged)]属性,即可实现需求:

use serde::{Serialize, Deserialize};
use serde_json::from_str;

#[derive(Serialize, Deserialize)]
struct Entry(String, String);

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum Action {
    #[serde(serialize_with = "serde::ser::Serializer::serialize_none")]
    #[serde(deserialize_as = "Option<()>")]
    Delete,
    Create(Entry),
}

type Actions = Vec<Action>;

#[test]
fn this_works() {
    from_str::<Actions>(r#"[["id", "value"], []]"#).unwrap();
}

#[test]
fn this_now_works() {
    from_str::<Actions>(r#"[["id", "value"], null]"#).unwrap();
}

原理说明

  • #[serde(deserialize_as = "Option<()>")]:指定Delete变体按Option<()>的逻辑反序列化,Option<()>会自动将JSON的null解析为None,进而映射到单元变体Delete。
  • #[serde(untagged)]:让serde忽略枚举标签,按变体类型匹配JSON值——Create(Entry)匹配数组格式的JSON,Delete匹配null。

若需保留Delete()带括号的单元变体写法,只需调整变体定义即可,属性无需修改:

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum Action {
    #[serde(serialize_with = "serde::ser::Serializer::serialize_none")]
    #[serde(deserialize_as = "Option<()>")]
    Delete(),
    Create(Entry),
}

内容的提问来源于stack exchange,提问作者Thomas W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 02:47:05