Reputation: 1871
The serde_json::to_string()
function will generate a string which may include null
for an Option<T>
, or 0
for a u32
. This makes the output larger, so I want to ignore these sorts of values.
I want to simplify the JSON string output of the following structure:
use serde_derive::Serialize; // 1.0.82
#[derive(Serialize)]
pub struct WeightWithOptionGroup {
pub group: Option<String>,
pub proportion: u32,
}
When group
is None
and proportion
is 0, the JSON string should be "{}"
Thanks for the answerHow do I change Serde's default implementation to return an empty object instead of null?, it can resolve Option
problem, but for 0
there is none solution.
Upvotes: 51
Views: 32604
Reputation: 7388
For those searching how to skip serialization for some enum
entries you can do this
#[derive(Serialize, Deserialize)]
enum Metadata {
App, // want this serialized
Ebook, // want this serialized
Empty // dont want this serialized
}
#[derive(Serialize, Deserialize)]
struct Request<'a> {
request_id: &'a str,
item_type: ItemType,
#[serde(skip_serializing_if = "Metadata::is_empty")]
metadata: Metadata,
}
impl Metadata {
fn is_empty(&self) -> bool {
match self {
Metadata::Empty => true,
_ => false,
}
}
}
Upvotes: 8
Reputation: 1871
The link Skip serializing field give me the answer.
And the fixed code:
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Ord, PartialOrd, Eq)]
pub struct WeightWithOptionGroup {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub group: Option<String>,
#[serde(skip_serializing_if = "is_zero")]
#[serde(default)]
pub proportion: u32,
}
/// This is only used for serialize
#[allow(clippy::trivially_copy_pass_by_ref)]
fn is_zero(num: &u32) -> bool {
*num == 0
}
Upvotes: 94
Reputation: 1697
There's a couple of ways you could do this:
skip_serialising_if
attribute to say when to skip them. This is much easier, but you'll have to remember to do it for every field.Upvotes: 3