I have the following structs:
#[derive(Debug, Serialize)]
struct Container {
field0: Field<f64>,
field1: Field<f64>,
}
#[derive(Debug, Serialize)]
struct Field<T> {
val: T,
#[serde(skip_serializing_if = "Option::is_none")]
doc: Option<String>,
}
For this instance:
Container {
field0: Field { val: 1.5, doc: Some("my documentation!") },
field1: Field { val: 2.0, doc: None }
}
I want the following YAML output (since doc is None):
field0:
val: 1.5
doc: my documentation!
field1: 2.0
Of course, the derived setup results in this:
field0:
val: 1.5
doc: my documentation!
field1:
val: 2.0
where val is serialized on a new line
I tried implementing Serialize for Field myself, but wasn't quite sure how to get the key name to go away, and how to get the value on the same line as the name
impl<T> Serialize for Field<T> where T: Serialize {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if self.doc.is_some() {
let mut state = serializer.serialize_struct("Field", 2)?;
state.serialize_field("val", &self.val)?;
state.serialize_field("doc", &self.doc)?;
state.end()
} else {
let mut state = serializer.serialize_struct("Field", 1)?;
state.serialize_field("", &self.val)?;
state.skip_field("doc")?;
state.end()
}
}
}
resulting in the output:
field0:
val: 1.5
doc: my documentation!
field1:
'': 2.0
How should I go about implementing it? Is there an easier/cleaner way?
Easy fix. If
docisNone, then you don't want to serialize a struct, just serialize the value directly:With your playground code produces: