diff --git a/derive/src/serde_json.rs b/derive/src/serde_json.rs index 0bedcd4..aae2387 100644 --- a/derive/src/serde_json.rs +++ b/derive/src/serde_json.rs @@ -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::::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 ); diff --git a/tests/json.rs b/tests/json.rs index d8b0bc8..542f040 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -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, } @@ -282,7 +282,7 @@ fn de_field_default() { } } - #[derive(DeJson)] + #[derive(DeJson, SerJson)] pub struct Test { a: i32, #[nserde(default)] @@ -302,6 +302,8 @@ fn de_field_default() { g: Option, #[nserde(default = "world")] h: Option, + #[nserde(default = 5.2)] + i: Option, } fn some_value() -> f32 { @@ -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(); @@ -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]