我有下面的代码,它按预期工作.

use serde::{ Serialize, Serializer };

// Define your struct with optional fields.
#[derive(Serialize)]
struct MyStruct {
    field1: i32,
    field2: Option<String>,
    #[serde(serialize_with = "custom_serialize_field3")]
    field3: Option<i32>,
    field4: i32,
    field5: Option<String>,
    custom_field: Option<String>,
}

// Define a custom serialization function for field3.
fn custom_serialize_field3<S>(field3: &Option<i32>, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer
{
    // Implement custom serialization logic for field3 here
    match field3 {
        Some(value) => serializer.serialize_i32(*value),
        None => serializer.serialize_i32(0),
    }
}

fn main() {
    let data = MyStruct {
        field1: 42,
        field2: Some("Hello".to_string()),
        field3: None,
        field4: 99,
        field5: Some("World".to_string()),
        custom_field: Some("CustomValue".to_string()), // Set a custom value here
    };

    let serialized = serde_json::to_string(&data).expect("Serialization failed");

    println!("{}", serialized);

    let data2 = MyStruct {
        field1: 42,
        field2: Some("Hello".to_string()),
        field3: Some(1000),
        field4: 99,
        field5: Some("World".to_string()),
        custom_field: Some("CustomValue".to_string()), // Set a custom value here
    };

    let serialized2 = serde_json::to_string(&data2).expect("Serialization failed");

    println!("{}", serialized2);
}

Working Playground

现在我有一个条件,当同时设置field3field5时,我们不应该序列化并返回错误.

error: cannot find attribute `serde` in this scope
 --> src/main.rs:7:7
  |
7 |     #[serde(serialize_with = "custom_serialize_field3")]
  |       ^^^^^
  |
  = note: `serde` is in scope, but it is a crate, not an attribute

为此,我try 使用Struct的定制序列化程序,但遇到了错误.我编写了以下代码,并从sstruct中删除了#[derive(Serialize)]:

impl Serialize for MyStruct {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        if self.field3.is_some() && self.field5.is_some() {
            return Err(serde::ser::Error::custom("Both field3 and field5 can't be present"));
        }

        let mut state = serializer.serialize_struct("MyStruct", 6)?;
        state.serialize_field("field1", &self.field1)?;
        state.serialize_field("field2", &self.field2)?;
        state.serialize_field("field3", &self.field3)?;
        state.serialize_field("field4", &self.field4)?;
        state.serialize_field("field5", &self.field5)?;
        state.serialize_field("custom_field", &self.custom_field)?;
        state.end()
    }
}

Playground

推荐答案

最简单的方法是在Serialize实现中实现0后备,并一起删除custom_serialize_field3:

impl Serialize for MyStruct {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if self.field3.is_some() && self.field5.is_some() {
            return Err(serde::ser::Error::custom(
                "Both field3 and field5 can't be present",
            ));
        }

        let mut state = serializer.serialize_struct("MyStruct", 6)?;
        state.serialize_field("field1", &self.field1)?;
        state.serialize_field("field2", &self.field2)?;
        state.serialize_field("field3", &self.field3.unwrap_or(0))?;
        state.serialize_field("field4", &self.field4)?;
        state.serialize_field("field5", &self.field5)?;
        state.serialize_field("custom_field", &self.custom_field)?;
        state.end()
    }
}

但如果你must使用custom_seralize_field3函数(正如你的问题标题所建议的),你可以做serde内部做的相同的事情:

impl Serialize for MyStruct {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if self.field3.is_some() && self.field5.is_some() {
            return Err(serde::ser::Error::custom(
                "Both field3 and field5 can't be present",
            ));
        }

        let mut state = serializer.serialize_struct("MyStruct", 6)?;
        state.serialize_field("field1", &self.field1)?;
        state.serialize_field("field2", &self.field2)?;
        state.serialize_field("field3", {
            #[derive(Serialize)]
            #[serde(transparent)]
            struct Wrapper<'a>(
                #[serde(serialize_with = "custom_serialize_field3")] &'a Option<i32>,
            );
            &Wrapper(&self.field3)
        })?;
        state.serialize_field("field4", &self.field4)?;
        state.serialize_field("field5", &self.field5)?;
        state.serialize_field("custom_field", &self.custom_field)?;
        state.end()
    }
}

Rust相关问答推荐

使用Rust s serde_json对混合数据类型进行优化'

如何在Rust中实现Functor trait?

如何装箱生命周期相关联的两个对象?

在泛型 struct 的字段声明中访问关联的Conant

如何定义实现同名但返回类型不同的 struct 的函数

如何在Rust中缩短数组

如何使用reqwest进行异步请求?

为什么我需要 to_string 函数的参考?

这个不安全的 Rust 代码有什么问题,所以它可以在 Windows 上运行,但不能在 Ubuntu 上运行?

Rust:为什么 &str 不使用 Into

如何返回 struct 体中向量的切片

Rust 并行获取对 ndarray 的每个元素的可变引用

为什么这个闭包没有实现Fn?

在不安全的 Rust 中存储对 struct 内部数据的静态引用是否合法?

打印 `format_args!` 时borrow 时临时值丢失

在 Rust 中返回对枚举变体的引用是个好主意吗?

匹配结果时的简洁日志(log)记录

TinyVec 如何与 Vec 大小相同?

list 中没有指定目标 - 必须存在 src/lib.rs、src/main.rs、[lib] 部分或 [[bin]] 部分

如何在 Rust 中使用特征标志来捕获多行代码?