Question

How do I avoid generating JSON when serializing a value that is null or a default value?

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 Optionproblem, but for 0 there is none solution.

 46  27657  46
1 Jan 1970

Solution

 89

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
}
2018-12-23

Solution

 5

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,
        }
    }
}
2022-09-28