Skip to content

Commit

Permalink
added serialize_none_as_null attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
birhburh committed Sep 7, 2024
1 parent d498d19 commit 7a8022e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
3 changes: 2 additions & 1 deletion derive/src/serde_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ pub fn derive_ser_json_struct(struct_: &Struct) -> TokenStream {

if field.ty.base() == "Option" {
let proxy_attr = crate::shared::attrs_proxy(&field.attributes);
let null_on_none = proxy_attr.is_none();
let serialize_none_as_null_attr = shared::attrs_serialize_none_as_null(&struct_.attributes);
let null_on_none = serialize_none_as_null_attr && proxy_attr.is_none();
let field_header = &format!("if first_field_was_serialized {{
s.conl();
}};
Expand Down
7 changes: 7 additions & 0 deletions derive/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ pub fn attrs_skip(attributes: &[crate::parse::Attribute]) -> bool {
.any(|attr| attr.tokens.len() == 1 && attr.tokens[0] == "skip")
}

#[cfg(feature = "json")]
pub fn attrs_serialize_none_as_null(attributes: &[crate::parse::Attribute]) -> bool {
attributes
.iter()
.any(|attr| attr.tokens.len() == 1 && attr.tokens[0] == "serialize_none_as_null")
}

#[cfg(any(feature = "binary", feature = "json"))]
pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (String, String) {
let generics: &Vec<_> = &struct_.generics;
Expand Down
35 changes: 24 additions & 11 deletions tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ fn rename() {
}

#[test]
fn de_ser_field_default() {
#[derive(DeJson, SerJson)]
fn de_field_default() {
#[derive(DeJson)]
struct Foo {
x: i32,
}
Expand All @@ -282,7 +282,7 @@ fn de_ser_field_default() {
}
}

#[derive(DeJson, SerJson)]
#[derive(DeJson)]
pub struct Test {
a: i32,
#[nserde(default)]
Expand All @@ -302,8 +302,6 @@ fn de_ser_field_default() {
g: Option<i32>,
#[nserde(default = "world")]
h: Option<String>,
#[nserde(default = 5.2)]
i: Option<f32>,
}

fn some_value() -> f32 {
Expand All @@ -312,8 +310,7 @@ fn de_ser_field_default() {

let json = r#"{
"a": 1,
"foo2": { "x": 3 },
"i": null
"foo2": { "x": 3 }
}"#;

let test: Test = DeJson::deserialize_json(json).unwrap();
Expand All @@ -327,11 +324,27 @@ fn de_ser_field_default() {
assert_eq!(test.h, Some(String::from("world")));
assert_eq!(test.foo.x, 23);
assert_eq!(test.foo2.x, 3);
assert_eq!(test.i, None);
}

let ser_json = r#"{"a":1,"foo":{"x":23},"foo2":{"x":3},"b":4.0,"c":3.0,"d":1,"e":"hello","f":{"x":3},"g":5,"h":"world","i":null}"#;
let serialized = SerJson::serialize_json(&test);
assert_eq!(serialized, ser_json);
#[test]
fn ser_none_as_null() {
#[derive(SerJson)]
struct Foo {
x: Option<i32>,
}

let a = Foo { x: None };
assert_eq!(SerJson::serialize_json(&a), r#"{}"#);

#[derive(SerJson)]
#[nserde(serialize_none_as_null)]
struct Foo2 {
x: Option<i32>,
}

let b = Foo2 { x: None };

assert_eq!(SerJson::serialize_json(&b), r#"{"x":null}"#);
}

#[test]
Expand Down

0 comments on commit 7a8022e

Please sign in to comment.