Как избежать генерации 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
}
}