Skip to content

Commit

Permalink
serde_json: serialize None as null if there is default attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
birhburh authored and knickish committed Sep 14, 2024
1 parent 418cbb9 commit 8bab6a3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
30 changes: 27 additions & 3 deletions derive/src/serde_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,40 @@ pub fn derive_ser_json_struct(struct_: &Struct) -> TokenStream {
let proxied_field = ser_proxy_guard(&format!("self.{struct_fieldname}"), field);

if field.ty.base() == "Option" {
let proxy_attr = crate::shared::attrs_proxy(&field.attributes);
let null_on_none = proxy_attr.is_none();
let field_header = &format!("if first_field_was_serialized {{
s.conl();
}};
first_field_was_serialized = true;
s.field(d+1, \"{}\");", json_fieldname);
l!(
s,
"if let Some(t) = &{} {{ if first_field_was_serialized {{ s.conl(); }};first_field_was_serialized = true;s.field(d+1, \"{}\");t.ser_json(d+1, s);}};",
"{}
if let Some(t) = &{} {{
{}
t.ser_json(d+1, s);
}} {}",
if null_on_none { field_header } else { "" },
proxied_field,
json_fieldname
if null_on_none { "" } else { field_header },
if null_on_none {
"else {{
Option::<i32>::ser_json(&None, d+1, s);
}}"
} else {
""
}
);
} else {
l!(
s,
"if first_field_was_serialized {{ s.conl(); }};first_field_was_serialized = true;s.field(d+1,\"{}\"); {}.ser_json(d+1, s);",
"if first_field_was_serialized {{
s.conl();
}};
first_field_was_serialized = true;
s.field(d+1,\"{}\");
{}.ser_json(d+1, s);",
json_fieldname,
proxied_field
);
Expand Down
16 changes: 12 additions & 4 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_field_default() {
#[derive(DeJson)]
fn de_ser_field_default() {
#[derive(DeJson, SerJson)]
struct Foo {
x: i32,
}
Expand All @@ -282,7 +282,7 @@ fn de_field_default() {
}
}

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

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

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

let test: Test = DeJson::deserialize_json(json).unwrap();
Expand All @@ -324,6 +327,11 @@ fn de_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]
Expand Down

0 comments on commit 8bab6a3

Please sign in to comment.