Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 887
llxxbb Avatar asked Dec 23 '18 01:12

llxxbb


2 Answers

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
}
like image 53
llxxbb Avatar answered Sep 24 '22 09:09

llxxbb


There's a couple of ways you could do this:

  • Mark each of the fields with a 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.
  • Write your own Serde serialiser that does this custom JSON form. This is more work, but shouldn't be too bad, especially given you can still use the stock JSON deserialiser.
like image 35
Tom Parker-Shemilt Avatar answered Sep 22 '22 09:09

Tom Parker-Shemilt