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

如何使用serde将JSON中"SI"/"NO"字符串字段反序列化为bool类型

实现方案

最简单的方式是使用serde提供的deserialize_with字段属性,绑定自定义的反序列化函数即可,步骤如下:

1. 引入依赖

确保你的Cargo.toml中已经引入serde相关依赖并开启derive特性:

serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

2. 编写自定义反序列化函数

use serde::{Deserialize, de::Deserializer};

fn si_no_to_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
    D: Deserializer<'de>,
{
    let s: &str = Deserialize::deserialize(deserializer)?;
    match s {
        "SI" => Ok(true),
        "NO" => Ok(false),
        other => Err(serde::de::Error::custom(format!("无效值:{},仅支持SI或NO", other))),
    }
}

3. 给结构体字段绑定反序列化逻辑

#[derive(Deserialize)]
pub struct Entry {
    #[serde(deserialize_with = "si_no_to_bool")]
    pub foo: bool,
}

测试示例

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 测试SI映射为true
    let json_si = r#"{"foo": "SI"}"#;
    let entry_si: Entry = serde_json::from_str(json_si)?;
    assert!(entry_si.foo);

    // 测试NO映射为false
    let json_no = r#"{"foo": "NO"}"#;
    let entry_no: Entry = serde_json::from_str(json_no)?;
    assert!(!entry_no.foo);

    Ok(())
}

复用方案(可选)

如果你有多个字段都需要用到SI/NO转bool的逻辑,可以封装为透明newtype避免重复写属性:

#[derive(Deserialize)]
#[serde(transparent)]
pub struct SiNoBool(#[serde(deserialize_with = "si_no_to_bool")] pub bool);

// 使用时直接指定类型即可
#[derive(Deserialize)]
pub struct Entry {
    pub foo: SiNoBool,
    // 其他同类型字段直接复用SiNoBool即可
    pub bar: SiNoBool,
}

// 取值时访问.0即可
// let foo_val = entry.foo.0;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:36:04