Как избежать генерации JSON при сериализации значения NULL или значения по умолчанию?

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

когда group является None а также proportion 0, строка JSON должна быть "{}"

Спасибо за ответ. Как мне изменить реализацию Serde по умолчанию, чтобы она возвращала пустой объект вместо null?, это может решить Optionпроблема, но для 0 нет решения

3 ответа

Решение

Ссылка Пропустить поле сериализации даст мне ответ.

И фиксированный код:

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

Есть несколько способов сделать это:

  • Отметьте каждое из полей с помощью skip_serialising_if атрибут, чтобы сказать, когда пропустить их. Это намного проще, но вы должны помнить, чтобы сделать это для каждой области.
  • Напишите свой собственный сериализатор Serde, который выполняет эту пользовательскую форму JSON. Это больше работы, но не должно быть слишком плохо, особенно если учесть, что вы все еще можете использовать стандартный десериализатор JSON.

Для тех, кто ищет, как пропустить сериализацию для некоторыхзаписи вы можете сделать это

      #[derive(Serialize, Deserialize)]
enum Metadata<'a> {
  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<'a>,
}

fn metadata_is_empty<'a>(metadata: &Metadata<'a>) -> bool {
  match metadata {
    Metadata::Empty => true,
    _ => false
  }
}
Другие вопросы по тегам