rust 如何避免在序列化空值或默认值时生成JSON?

q3qa4bjr  于 2023-08-05  发布在  其他
关注(0)|答案(3)|浏览(138)

serde_json::to_string()函数将生成一个字符串,其中可能包括null(对于Option<T>)或0(对于u32)。这使得输出更大,所以我想忽略这些类型的值。
我想简化以下结构的JSON字符串输出:

use serde_derive::Serialize; // 1.0.82

#[derive(Serialize)]
pub struct WeightWithOptionGroup {
    pub group: Option<String>,
    pub proportion: u32,
}

字符串
groupNoneproportion为0时,JSON字符串应为"{}"
感谢How do I change Serde's default implementation to return an empty object instead of null?的回答,它可以解决Option问题,但对于0没有解决方案。

hc2pp10m

hc2pp10m1#

Skip serializing field链接给予我答案。
固定代码:

#[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
}

字符串

rhfm7lfc

rhfm7lfc2#

有几种方法可以做到这一点:

  • 使用skip_serialising_if属性标记每个字段,以指示何时跳过它们。这要容易得多,但你必须记住对每个字段都这样做。
  • Write your own Serde serialiser,它会生成这个自定义JSON表单。这是更多的工作,但不应该太糟糕,特别是考虑到您仍然可以使用股票JSON反序列化器。
rfbsl7qr

rfbsl7qr3#

对于那些搜索如何跳过某些enum条目的序列化的用户,可以这样做

#[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,
        }
    }
}

字符串

相关问题