-
|
Scenario: You're serializing a struct that contains a type from a foreign crate that either doesn't implement Currently, this can be accomplished by defining two different use serde::{Serialize, Serializer};
use serde_with::skip_serializing_none;
struct ForeignType;
#[skip_serializing_none]
#[derive(Serialize)]
struct Data {
#[serde(serialize_with = "serialize_foreign")]
field: ForeignType,
#[serde(serialize_with = "serialize_option_foreign")]
nullable: Option<ForeignType>,
}
fn main() {
let data1 = Data {
field: ForeignType,
nullable: Some(ForeignType),
};
assert_eq!(
serde_json::to_string(&data1).unwrap(),
r#"{"field":"<Foreign type>","nullable":"<Foreign type>"}"#
);
let data2 = Data {
field: ForeignType,
nullable: None,
};
assert_eq!(
serde_json::to_string(&data2).unwrap(),
r#"{"field":"<Foreign type>"}"#
);
println!("OK");
}
fn foreign2string(_: &ForeignType) -> String {
String::from("<Foreign type>")
}
fn serialize_foreign<S: Serializer>(value: &ForeignType, serializer: S) -> Result<S::Ok, S::Error> {
foreign2string(value).serialize(serializer)
}
fn serialize_option_foreign<S: Serializer>(
value: &Option<ForeignType>,
serializer: S,
) -> Result<S::Ok, S::Error> {
value.as_ref().map(foreign2string).serialize(serializer)
}However, I really feel like this sort of scenario would or should be something that #[serde_as]
#[skip_serializing_none]
#[derive(Serialize)]
struct Data {
#[serde(serialize_with = "serialize_foreign")]
field: ForeignType,
#[serde_as(as = "Option<serialize_foreign>")]
nullable: Option<ForeignType>,
}but this doesn't compile. Does |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
This is exactly what The bottom example that you call "abuse" is basically what you have to do, except you can't use a function as a type like this. So you have to use a new type and implement |
Beta Was this translation helpful? Give feedback.
This is exactly what
serde_withhelps with. I don't know why you think that serializing anOption<T>is a problem. There is even special support to make working withOptionsimpler and more intuitive: https://docs.rs/serde_with/3.4.0/serde_with/guide/serde_as/index.html#deserializing-optional-fieldsThe bottom example that you call "abuse" is basically what you have to do, except you can't use a function as a type like this. So you have to use a new type and implement
SerializeAs, but that is just some boilerplate syntax changes. Check out the user guide for how to implementSerializeAs. It is very simple since you already have the function: https://docs.rs/serde_with/3.4.0/serde_with/gui…