如何在结构体的自定义Serializer中使用serde的serialize_with
解决方案:保留自定义字段序列化并添加序列化校验
方法一:手动实现Serialize trait(完全控制流程)
手动实现时,可通过serde提供的SerializeStruct API构建序列化状态,同时调用自定义序列化函数处理field3,并在序列化前加入校验逻辑。
use serde::{Serialize, Serializer}; use serde::ser::Error; // 保留原有的自定义序列化函数 fn custom_serialize_field3<S>(value: &Option<i32>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { // 示例自定义逻辑:将数字转为字符串序列化 match value { Some(v) => serializer.serialize_str(&v.to_string()), None => serializer.serialize_none(), } } #[derive(Debug)] struct MyStruct { field1: String, field2: u32, field3: Option<i32>, field4: bool, field5: Option<String>, } impl Serialize for MyStruct { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { // 校验逻辑:field3与field5同时存在则返回错误 if self.field3.is_some() && self.field5.is_some() { return Err(S::Error::custom("field3与field5不能同时存在")); } // 构建结构体序列化状态 let mut state = serializer.serialize_struct("MyStruct", 5)?; // 序列化普通字段 state.serialize_field("field1", &self.field1)?; state.serialize_field("field2", &self.field2)?; // 调用自定义函数序列化field3,等效于#[serde(serialize_with)] state.serialize_field_with("field3", &self.field3, custom_serialize_field3)?; state.serialize_field("field4", &self.field4)?; state.serialize_field("field5", &self.field5)?; // 完成序列化 state.end() } }
方法二:结合derive(Serialize)与校验函数(更简洁)
如果无需修改其他字段的序列化逻辑,可保留#[derive(Serialize)]和原有的serialize_with属性,通过封装校验函数实现需求:
use serde::{Serialize, Serializer}; use serde::ser::Error; fn custom_serialize_field3<S>(value: &Option<i32>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { match value { Some(v) => serializer.serialize_str(&v.to_string()), None => serializer.serialize_none(), } } // 保留derive和原有的serde属性 #[derive(Serialize, Debug)] struct MyStruct { field1: String, field2: u32, #[serde(serialize_with = "custom_serialize_field3")] field3: Option<i32>, field4: bool, field5: Option<String>, } impl MyStruct { // 封装带校验的序列化方法 pub fn serialize_with_validation<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { if self.field3.is_some() && self.field5.is_some() { return Err(S::Error::custom("field3与field5不能同时存在")); } // 调用derive自动生成的序列化逻辑 self.serialize(serializer) } }
关键说明
- 手动实现时,
serialize_field_with是#[serde(serialize_with)]的手动等效调用,用于指定字段的自定义序列化函数 - 两种方法均能保留
field3的自定义序列化逻辑,同时实现校验需求 - 方法二更适合仅需添加校验、无需修改其他字段序列化逻辑的场景,代码更简洁易维护
内容的提问来源于stack exchange,提问作者Harshit Bhat
相关产品推荐
相关产品推荐

