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

使用Serde反序列化时,如何保留对应序列化数据的副本?

解决Rust Serde反序列化时保留嵌套结构体原始JSON的问题

实现思路

要实现反序列化时同时保留嵌套结构体的原始JSON字符串,需要借助Serde的自定义反序列化逻辑,结合serde_json::RawValue来捕获原始JSON片段:

  1. 为InnerStruct实现自定义的Deserialize trait,在反序列化过程中先获取对应的原始JSON字符串;
  2. 从原始JSON片段中解析出inner_value等业务字段;
  3. 构造最终的InnerStruct实例,同时存入原始JSON字符串和解析后的字段值。

完整代码实现

首先确保Cargo.toml中包含必要依赖:

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

然后编写Rust代码:

use serde::de::{self, Deserialize, Deserializer};
use serde_json::value::RawValue;

#[derive(Deserialize)]
struct LargerStruct {
    value: i32,
    inner: InnerStruct,
}

struct InnerStruct {
    this_json: String,
    inner_value: i32,
}

// 辅助结构体,用于解析InnerStruct的业务字段
#[derive(Deserialize)]
struct InnerStructHelper {
    inner_value: i32,
}

// 为InnerStruct实现自定义反序列化逻辑
impl<'de> Deserialize<'de> for InnerStruct {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // 用RawValue捕获原始JSON片段,保留原始格式和空格
        let raw_json = RawValue::deserialize(deserializer)?;
        let this_json = raw_json.get().to_string();
        
        // 从原始JSON片段解析出业务字段
        let helper = InnerStructHelper::deserialize(&*raw_json)
            .map_err(de::Error::custom)?;
        
        Ok(InnerStruct {
            this_json,
            inner_value: helper.inner_value,
        })
    }
}

fn main() {
    let json = r#"
        {
          "value": 42, 
          "inner": { "inner_value": 100 }
        }
    "#;

    // 反序列化LargerStruct,InnerStruct会自动使用自定义逻辑
    let val: LargerStruct = serde_json::from_str(json).unwrap();

    assert_eq!(&val.inner.this_json, r#"{ "inner_value": 100 }"#);
}

关键细节说明

  • RawValue的作用:serde_json::RawValue可以直接获取反序列化时的原始JSON字节对应的字符串,完全保留输入的格式(包括空格、换行),避免了重新序列化导致的格式变化。
  • 辅助结构体的意义:InnerStructHelper简化了业务字段的解析,利用Serde自动派生的Deserialize能力,无需手动从JSON Value中提取字段,减少冗余代码。
  • 自定义反序列化的范围:仅需要为需要保留原始JSON的InnerStruct实现自定义逻辑,外层的LargerStruct可以继续使用自动派生的Deserialize,不影响其他字段的解析效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:45:15