feat!: remove requirement to Default

issue #175 #144
This commit is contained in:
Marc-Antoine Arnaud 2024-02-06 00:36:58 +01:00
parent 3413e98710
commit 82df2e15b9
12 changed files with 190 additions and 159 deletions

View File

@ -1,7 +1,7 @@
// related to issue https://github.com/media-io/yaserde/issues/15 // related to issue https://github.com/media-io/yaserde/issues/15
use yaserde::*; use yaserde::*;
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
#[yaserde( #[yaserde(
prefix = "ss", prefix = "ss",
namespace = "x: urn:schemas-microsoft-com:office:excel", namespace = "x: urn:schemas-microsoft-com:office:excel",
@ -14,7 +14,7 @@ struct Workbook {
worksheet: Worksheet, worksheet: Worksheet,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
#[yaserde( #[yaserde(
prefix = "ss", prefix = "ss",
namespace = "x: urn:schemas-microsoft-com:office:excel", namespace = "x: urn:schemas-microsoft-com:office:excel",
@ -29,7 +29,7 @@ struct Worksheet {
ws_name: String, ws_name: String,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
#[yaserde( #[yaserde(
prefix = "ss", prefix = "ss",
namespace = "x: urn:schemas-microsoft-com:office:excel", namespace = "x: urn:schemas-microsoft-com:office:excel",
@ -57,7 +57,7 @@ struct Table {
rows: Vec<Row>, rows: Vec<Row>,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
#[yaserde( #[yaserde(
prefix = "ss", prefix = "ss",
namespace = "x: urn:schemas-microsoft-com:office:excel", namespace = "x: urn:schemas-microsoft-com:office:excel",

View File

@ -1,7 +1,7 @@
// related to issue https://github.com/media-io/yaserde/issues/3 // related to issue https://github.com/media-io/yaserde/issues/3
use yaserde::*; use yaserde::*;
#[derive(Default, Debug, Clone, PartialEq, YaDeserialize)] #[derive(Debug, Clone, PartialEq, YaDeserialize)]
#[yaserde(root = "layout")] #[yaserde(root = "layout")]
pub struct Layout { pub struct Layout {
#[yaserde(attribute)] #[yaserde(attribute)]
@ -17,7 +17,7 @@ pub struct Layout {
pub tabpage: Vec<Tabpage>, pub tabpage: Vec<Tabpage>,
} }
#[derive(Default, Debug, Clone, PartialEq, YaDeserialize)] #[derive(Debug, Clone, PartialEq, YaDeserialize)]
pub struct Tabpage { pub struct Tabpage {
#[yaserde(attribute, rename = "name")] #[yaserde(attribute, rename = "name")]
pub named: String, pub named: String,
@ -48,7 +48,7 @@ pub struct Tabpage {
pub control: Vec<Control>, pub control: Vec<Control>,
} }
#[derive(Default, Debug, Clone, PartialEq, YaDeserialize)] #[derive(Debug, Clone, PartialEq, YaDeserialize)]
pub struct Control { pub struct Control {
#[yaserde(attribute, rename = "name")] #[yaserde(attribute, rename = "name")]
pub named: String, pub named: String,
@ -63,27 +63,27 @@ pub struct Control {
#[yaserde(attribute)] #[yaserde(attribute)]
pub color: String, pub color: String,
#[yaserde(attribute)] #[yaserde(attribute)]
pub scalef: f32, pub scalef: Option<f32>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub scalet: f32, pub scalet: Option<f32>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub local_off: bool, pub local_off: Option<bool>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub sp: bool, pub sp: Option<bool>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub sr: bool, pub sr: Option<bool>,
pub midi: Vec<Midi>, pub midi: Vec<Midi>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub response: String, pub response: Option<String>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub inverted: String, pub inverted: Option<String>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub centered: String, pub centered: Option<String>,
#[yaserde(attribute)] #[yaserde(attribute)]
pub norollover: String, pub norollover: Option<String>,
} }
#[derive(Default, Debug, Clone, PartialEq, YaDeserialize)] #[derive(Debug, Clone, PartialEq, YaDeserialize)]
pub struct Midi { pub struct Midi {
#[yaserde(attribute)] #[yaserde(attribute)]
pub var: String, pub var: String,

View File

@ -1,7 +1,7 @@
// related to issue https://github.com/media-io/yaserde/issues/11 // related to issue https://github.com/media-io/yaserde/issues/11
use yaserde::*; use yaserde::*;
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
#[yaserde(root = "DOMSymbolItem")] #[yaserde(root = "DOMSymbolItem")]
struct Level { struct Level {
#[yaserde(attribute)] #[yaserde(attribute)]
@ -11,13 +11,13 @@ struct Level {
timeline: Timeline, timeline: Timeline,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
struct Timeline { struct Timeline {
#[yaserde(rename = "DOMTimeline")] #[yaserde(rename = "DOMTimeline")]
timeline: DOMTimeline, timeline: DOMTimeline,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
struct DOMTimeline { struct DOMTimeline {
#[yaserde(attribute, rename = "name")] #[yaserde(attribute, rename = "name")]
named: String, named: String,
@ -28,13 +28,13 @@ struct DOMTimeline {
layers: Layers, layers: Layers,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
struct Layers { struct Layers {
#[yaserde(rename = "DOMLayer")] #[yaserde(rename = "DOMLayer")]
dom_layer: Vec<DOMLayer>, dom_layer: Vec<DOMLayer>,
} }
#[derive(YaDeserialize, Default, Debug, PartialEq)] #[derive(YaDeserialize, Debug, PartialEq)]
struct DOMLayer { struct DOMLayer {
#[yaserde(attribute, rename = "name")] #[yaserde(attribute, rename = "name")]
named: String, named: String,

View File

@ -1,6 +1,6 @@
use yaserde::YaSerialize; use yaserde::YaSerialize;
#[derive(Default, PartialEq, Debug, YaSerialize)] #[derive(PartialEq, Debug, YaSerialize)]
struct CpuDef { struct CpuDef {
#[yaserde(child)] #[yaserde(child)]
name: String, name: String,
@ -18,7 +18,7 @@ struct CpuDef {
vendorsystickconfig: bool, vendorsystickconfig: bool,
} }
#[derive(Default, PartialEq, Debug, YaSerialize)] #[derive(PartialEq, Debug, YaSerialize)]
struct Field { struct Field {
name: String, name: String,
#[yaserde(child)] #[yaserde(child)]
@ -29,7 +29,7 @@ struct Field {
access: String, access: String,
} }
#[derive(Default, PartialEq, Debug, YaSerialize)] #[derive(PartialEq, Debug, YaSerialize)]
struct Register { struct Register {
#[yaserde(child)] #[yaserde(child)]
name: String, name: String,
@ -49,7 +49,7 @@ struct Register {
fields: Vec<Field>, fields: Vec<Field>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize)] #[derive(PartialEq, Debug, YaSerialize)]
struct Peripheral { struct Peripheral {
#[yaserde(child)] #[yaserde(child)]
name: String, name: String,
@ -69,7 +69,7 @@ struct Peripheral {
registers: Vec<Register>, registers: Vec<Register>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize)] #[derive(PartialEq, Debug, YaSerialize)]
struct DevAttrs { struct DevAttrs {
#[yaserde(child)] #[yaserde(child)]
vendor: String, vendor: String,
@ -103,7 +103,7 @@ struct DevAttrs {
peripherals: Vec<Peripheral>, peripherals: Vec<Peripheral>,
} }
#[derive(Default, PartialEq, Debug, YaSerialize)] #[derive(PartialEq, Debug, YaSerialize)]
#[yaserde(rename = "device")] #[yaserde(rename = "device")]
struct Device { struct Device {
#[yaserde(attribute)] #[yaserde(attribute)]

View File

@ -16,7 +16,7 @@
//!```rust //!```rust
//! use yaserde_derive::YaSerialize; //! use yaserde_derive::YaSerialize;
//! //!
//! #[derive(Default, PartialEq, Debug, YaSerialize)] //! #[derive(PartialEq, Debug, YaSerialize)]
//! #[yaserde(rename = "device")] //! #[yaserde(rename = "device")]
//! struct Device { //! struct Device {
//! #[yaserde(attribute)] //! #[yaserde(attribute)]
@ -29,7 +29,7 @@
//! attributes: DeviceAttributes //! attributes: DeviceAttributes
//! } //! }
//! //!
//! #[derive(Default, PartialEq, Debug, YaSerialize)] //! #[derive(PartialEq, Debug, YaSerialize)]
//! struct DeviceAttributes { //! struct DeviceAttributes {
//! #[yaserde(child)] //! #[yaserde(child)]
//! vendor: String, //! vendor: String,

View File

@ -125,7 +125,7 @@ fn module_inclusion() {
init(); init();
mod module { mod module {
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
#[yaserde(rename = "module")] #[yaserde(rename = "module")]
pub struct Module { pub struct Module {
#[yaserde(attribute)] #[yaserde(attribute)]

View File

@ -115,7 +115,7 @@ fn de_multiple_segments() {
init(); init();
mod other_mod { mod other_mod {
#[derive(YaDeserialize, PartialEq, Debug, Default)] #[derive(YaDeserialize, PartialEq, Debug)]
pub struct Page { pub struct Page {
pub number: i32, pub number: i32,
pub text: String, pub text: String,
@ -216,14 +216,6 @@ fn de_attributes() {
subitem: String, subitem: String,
} }
impl Default for SubStruct {
fn default() -> SubStruct {
SubStruct {
subitem: "".to_string(),
}
}
}
let content = "<base item=\"something\"><sub subitem=\"sub-something\"></sub></base>"; let content = "<base item=\"something\"><sub subitem=\"sub-something\"></sub></base>";
convert_and_validate!( convert_and_validate!(
content, content,
@ -246,7 +238,7 @@ fn de_attributes_custom_deserializer() {
use xml::reader::XmlEvent; use xml::reader::XmlEvent;
#[derive(Debug, Default, PartialEq)] #[derive(Debug, PartialEq)]
pub struct Attributes { pub struct Attributes {
pub items: Vec<String>, pub items: Vec<String>,
} }
@ -274,7 +266,7 @@ fn de_attributes_custom_deserializer() {
} }
} }
#[derive(Default, YaDeserialize, PartialEq, Debug)] #[derive(YaDeserialize, PartialEq, Debug)]
pub struct Struct { pub struct Struct {
#[yaserde(attribute)] #[yaserde(attribute)]
attr_option_string: Option<String>, attr_option_string: Option<String>,
@ -318,7 +310,7 @@ fn de_attributes_complex() {
} }
} }
#[derive(Default, YaDeserialize, PartialEq, Debug)] #[derive(YaDeserialize, PartialEq, Debug)]
pub struct Struct { pub struct Struct {
#[yaserde(attribute)] #[yaserde(attribute)]
attr_option_string: Option<String>, attr_option_string: Option<String>,
@ -349,7 +341,7 @@ fn de_attributes_complex() {
fn de_attributes_with_same_name_field() { fn de_attributes_with_same_name_field() {
init(); init();
#[derive(Default, YaDeserialize, PartialEq, Debug)] #[derive(YaDeserialize, PartialEq, Debug)]
pub struct Struct { pub struct Struct {
#[yaserde(attribute, rename = "content")] #[yaserde(attribute, rename = "content")]
attribute: Option<String>, attribute: Option<String>,
@ -406,14 +398,6 @@ fn de_rename() {
subitem: String, subitem: String,
} }
impl Default for SubStruct {
fn default() -> SubStruct {
SubStruct {
subitem: "".to_string(),
}
}
}
let content = "<base Item=\"something\"><sub sub_item=\"sub_something\"></sub><maj.min.bug>2.0.1</maj.min.bug></base>"; let content = "<base Item=\"something\"><sub sub_item=\"sub_something\"></sub><maj.min.bug>2.0.1</maj.min.bug></base>";
convert_and_validate!( convert_and_validate!(
content, content,
@ -450,15 +434,6 @@ fn de_text_content_with_attributes() {
text: String, text: String,
} }
impl Default for SubStruct {
fn default() -> SubStruct {
SubStruct {
subitem: "".to_string(),
text: "".to_string(),
}
}
}
let content = let content =
"<base Item=\"something\"><sub sub_item=\"sub_something\">text_content</sub></base>"; "<base Item=\"something\"><sub sub_item=\"sub_something\">text_content</sub></base>";
convert_and_validate!( convert_and_validate!(
@ -525,16 +500,6 @@ fn de_enum() {
blue: String, blue: String,
} }
impl Default for RGBColor {
fn default() -> RGBColor {
RGBColor {
red: "0".to_string(),
green: "0".to_string(),
blue: "0".to_string(),
}
}
}
let content = let content =
"<?xml version=\"1.0\" encoding=\"utf-8\"?><base><background>Black</background></base>"; "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><background>Black</background></base>";
convert_and_validate!( convert_and_validate!(
@ -593,7 +558,7 @@ fn de_complex_enum() {
background: Color, background: Color,
} }
#[derive(YaDeserialize, PartialEq, Debug, Default)] #[derive(YaDeserialize, PartialEq, Debug)]
pub struct OtherStruct { pub struct OtherStruct {
fi: i32, fi: i32,
se: i32, se: i32,
@ -824,7 +789,7 @@ fn de_name_issue_21() {
fn de_custom() { fn de_custom() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
struct Date { struct Date {
#[yaserde(rename = "Year")] #[yaserde(rename = "Year")]
year: i32, year: i32,
@ -834,7 +799,7 @@ fn de_custom() {
day: Day, day: Day,
} }
#[derive(Default, PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct Day { struct Day {
value: i32, value: i32,
} }
@ -883,7 +848,7 @@ fn de_custom() {
fn de_subitem_issue_12() { fn de_subitem_issue_12() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Struct { pub struct Struct {
id: i32, id: i32,
} }
@ -906,12 +871,12 @@ fn de_subitem_issue_12() {
fn de_subitem_issue_12_with_sub() { fn de_subitem_issue_12_with_sub() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct SubStruct { pub struct SubStruct {
id: i32, id: i32,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Struct { pub struct Struct {
id: i32, id: i32,
#[yaserde(rename = "SubStruct")] #[yaserde(rename = "SubStruct")]
@ -939,7 +904,7 @@ fn de_subitem_issue_12_with_sub() {
fn de_subitem_issue_12_attributes() { fn de_subitem_issue_12_attributes() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Struct { pub struct Struct {
#[yaserde(attribute)] #[yaserde(attribute)]
id: i32, id: i32,
@ -960,13 +925,13 @@ fn de_subitem_issue_12_attributes() {
fn de_subitem_issue_12_attributes_with_sub() { fn de_subitem_issue_12_attributes_with_sub() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct SubStruct { pub struct SubStruct {
#[yaserde(attribute)] #[yaserde(attribute)]
id: i32, id: i32,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Struct { pub struct Struct {
#[yaserde(attribute)] #[yaserde(attribute)]
id: i32, id: i32,
@ -994,17 +959,23 @@ fn de_subitem_issue_12_attributes_with_sub() {
fn de_same_field_name_sub() { fn de_same_field_name_sub() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct SubStruct { pub struct SubStruct {
sub: Option<i32>, sub: Option<i32>,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Struct { pub struct Struct {
sub: SubStruct, sub: SubStruct,
} }
convert_and_validate!("<Struct><sub /></Struct>", Struct, Struct::default()); convert_and_validate!(
"<Struct><sub /></Struct>",
Struct,
Struct {
sub: SubStruct { sub: None }
}
);
convert_and_validate!( convert_and_validate!(
"<Struct><sub><sub>42</sub></sub></Struct>", "<Struct><sub><sub>42</sub></sub></Struct>",
@ -1019,22 +990,28 @@ fn de_same_field_name_sub() {
fn de_same_field_name_sub_sub() { fn de_same_field_name_sub_sub() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct SubSubStruct { pub struct SubSubStruct {
sub: i32, sub: i32,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct SubStruct { pub struct SubStruct {
sub: Option<SubSubStruct>, sub: Option<SubSubStruct>,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Struct { pub struct Struct {
sub: SubStruct, sub: SubStruct,
} }
convert_and_validate!("<Struct><sub /></Struct>", Struct, Struct::default()); convert_and_validate!(
"<Struct><sub /></Struct>",
Struct,
Struct {
sub: SubStruct { sub: None }
}
);
convert_and_validate!( convert_and_validate!(
"<Struct> "<Struct>
@ -1059,7 +1036,7 @@ fn de_same_field_name_sub_sub() {
fn de_same_field_name_but_some_other_fields_or_something() { fn de_same_field_name_but_some_other_fields_or_something() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
#[yaserde(rename = "foo")] #[yaserde(rename = "foo")]
pub struct FooOuter { pub struct FooOuter {
pub other: bool, pub other: bool,
@ -1067,7 +1044,7 @@ fn de_same_field_name_but_some_other_fields_or_something() {
pub foo: Option<FooInner>, pub foo: Option<FooInner>,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
pub struct FooInner { pub struct FooInner {
pub blah: bool, pub blah: bool,
} }
@ -1103,7 +1080,7 @@ fn de_attribute_sequence() {
Bar, Bar,
} }
#[derive(Default, Debug, PartialEq, YaDeserialize)] #[derive(Debug, PartialEq, YaDeserialize)]
pub struct Outer { pub struct Outer {
#[yaserde(attribute, rename = "seq1")] #[yaserde(attribute, rename = "seq1")]
seq1: Vec<i32>, seq1: Vec<i32>,
@ -1130,7 +1107,7 @@ fn de_nested_macro_rules() {
macro_rules! float_attrs { macro_rules! float_attrs {
($type:ty) => { ($type:ty) => {
#[derive(Default, PartialEq, Debug, YaDeserialize)] #[derive(PartialEq, Debug, YaDeserialize)]
pub struct Outer { pub struct Outer {
#[yaserde(attribute)] #[yaserde(attribute)]
pub inner: Option<$type>, pub inner: Option<$type>,

View File

@ -11,7 +11,7 @@ fn init() {
fn basic_flatten() { fn basic_flatten() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct DateTime { struct DateTime {
#[yaserde(flatten)] #[yaserde(flatten)]
date: Date, date: Date,
@ -20,7 +20,7 @@ fn basic_flatten() {
kind: DateKind, kind: DateKind,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct Date { struct Date {
year: i32, year: i32,
month: i32, month: i32,
@ -31,18 +31,18 @@ fn basic_flatten() {
optional_extra: Option<OptionalExtra>, optional_extra: Option<OptionalExtra>,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
pub struct Extra { pub struct Extra {
week: i32, week: i32,
century: i32, century: i32,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
pub struct OptionalExtra { pub struct OptionalExtra {
lunar_day: i32, lunar_day: i32,
} }
#[derive(PartialEq, Debug, YaDeserialize, YaSerialize, Default)] #[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)]
pub enum DateKind { pub enum DateKind {
#[yaserde(rename = "holidays")] #[yaserde(rename = "holidays")]
Holidays(Vec<String>), Holidays(Vec<String>),
@ -150,7 +150,7 @@ fn root_flatten_enum() {
fn flatten_attribute() { fn flatten_attribute() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct HtmlText { struct HtmlText {
#[yaserde(flatten)] #[yaserde(flatten)]
text_attributes: TextAttributes, text_attributes: TextAttributes,
@ -158,7 +158,7 @@ fn flatten_attribute() {
display: String, display: String,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct TextAttributes { struct TextAttributes {
#[yaserde(attribute)] #[yaserde(attribute)]
bold: bool, bold: bool,
@ -166,7 +166,7 @@ fn flatten_attribute() {
font: FontAttributes, font: FontAttributes,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
#[yaserde(namespace = "ns: http://www.sample.com/ns/domain")] #[yaserde(namespace = "ns: http://www.sample.com/ns/domain")]
pub struct FontAttributes { pub struct FontAttributes {
#[yaserde(attribute, prefix = "ns")] #[yaserde(attribute, prefix = "ns")]
@ -192,20 +192,20 @@ fn flatten_attribute() {
fn flatten_attribute_and_child() { fn flatten_attribute_and_child() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct Node { struct Node {
#[yaserde(flatten)] #[yaserde(flatten)]
base: Base, base: Base,
value: StringValue, value: StringValue,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct Base { struct Base {
#[yaserde(attribute)] #[yaserde(attribute)]
id: String, id: String,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct StringValue { struct StringValue {
#[yaserde(text)] #[yaserde(text)]
string: String, string: String,
@ -230,14 +230,14 @@ fn flatten_attribute_and_child() {
fn flatten_name_in_unknown_child() { fn flatten_name_in_unknown_child() {
init(); init();
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
pub struct Node { pub struct Node {
#[yaserde(flatten)] #[yaserde(flatten)]
base: Base, base: Base,
value: Value, value: Value,
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)] #[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct Base { struct Base {
#[yaserde(attribute)] #[yaserde(attribute)]
id: String, id: String,
@ -248,15 +248,15 @@ fn flatten_name_in_unknown_child() {
Foo(FooStruct), Foo(FooStruct),
} }
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)]
struct FooStruct {}
impl Default for Value { impl Default for Value {
fn default() -> Self { fn default() -> Self {
Self::Foo(FooStruct::default()) Self::Foo(FooStruct {})
} }
} }
#[derive(PartialEq, Debug, YaDeserialize, YaSerialize)]
struct FooStruct {}
let model = Node { let model = Node {
base: Base { base: Base {
id: "Foo".to_owned(), id: "Foo".to_owned(),

View File

@ -145,7 +145,7 @@ fn struct_sub_namespace_definition() {
fn struct_namespace_nested() { fn struct_namespace_nested() {
init(); init();
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
#[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")] #[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")]
struct A { struct A {
#[yaserde(prefix = "nsa")] #[yaserde(prefix = "nsa")]
@ -180,7 +180,7 @@ fn struct_namespace_nested() {
fn struct_namespace_nested_defined_at_root() { fn struct_namespace_nested_defined_at_root() {
init(); init();
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
#[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")] #[yaserde(prefix = "nsa", namespace = "nsa: http://www.sample.com/ns/a")]
struct A { struct A {
#[yaserde(prefix = "nsa")] #[yaserde(prefix = "nsa")]
@ -326,13 +326,12 @@ fn struct_default_namespace_via_attribute_with_prefix() {
fn enum_namespace() { fn enum_namespace() {
init(); init();
#[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)]
#[yaserde( #[yaserde(
rename = "root", rename = "root",
prefix = "ns", prefix = "ns",
namespace = "ns: http://www.sample.com/ns/domain" namespace = "ns: http://www.sample.com/ns/domain"
)] )]
#[derive(Default)]
pub enum XmlStruct { pub enum XmlStruct {
#[yaserde(prefix = "ns")] #[yaserde(prefix = "ns")]
#[default] #[default]

View File

@ -85,7 +85,7 @@ fn option_struct() {
field: SubTest, field: SubTest,
} }
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
struct SubTest { struct SubTest {
content: Option<String>, content: Option<String>,
} }
@ -111,7 +111,7 @@ fn option_bool_no_crash_on_bad_input() {
field: SubTest, field: SubTest,
} }
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
struct SubTest { struct SubTest {
#[yaserde(attribute)] #[yaserde(attribute)]
content: Option<bool>, content: Option<bool>,
@ -122,3 +122,41 @@ fn option_bool_no_crash_on_bad_input() {
assert!(result.is_err()); assert!(result.is_err());
} }
#[cfg(test)]
mod tests {
use super::*;
use yaserde::de::from_str;
#[derive(Debug, YaDeserialize, YaSerialize)]
pub struct Car {
#[yaserde(rename = "CarColor")]
color: String,
#[yaserde(rename = "CarBrand")]
brand: String,
}
#[derive(Debug, YaDeserialize, YaSerialize)]
pub struct Person {
#[yaserde(flatten)]
pub car: Option<Car>,
}
#[test]
fn deserialize_without_car() {
let person = r#"<?xml version="1.0" encoding="utf-8"?>
<Person>
<EyeColor>brown</EyeColor>
<Age>25</Age>
<HasHome>true</HasHome>
<HasGarden>false</HasGarden>
</Person>
"#;
let person: Person = from_str(person).unwrap();
let expected_person = Person { car: None };
assert_eq!(person.car.is_none(), expected_person.car.is_none());
}
}

View File

@ -5,14 +5,24 @@ use quote::quote;
pub fn build_default_value( pub fn build_default_value(
field: &YaSerdeField, field: &YaSerdeField,
field_type: Option<TokenStream>, field_type: Option<TokenStream>,
value: TokenStream,
) -> Option<TokenStream> { ) -> Option<TokenStream> {
let label = field.get_value_label(); let label = field.get_value_label();
let default_value = field let field_type = field_type
.get_default_function() .map(|field_type| quote!(: Option::<#field_type>))
.map(|default_function| quote!(#default_function())) .unwrap_or_default();
.unwrap_or_else(|| quote!(#value));
Some(quote! {
#[allow(unused_mut)]
let mut #label #field_type = None;
})
}
pub fn build_default_vec_value(
field: &YaSerdeField,
field_type: Option<TokenStream>,
) -> Option<TokenStream> {
let label = field.get_value_label();
let field_type = field_type let field_type = field_type
.map(|field_type| quote!(: #field_type)) .map(|field_type| quote!(: #field_type))
@ -20,6 +30,6 @@ pub fn build_default_value(
Some(quote! { Some(quote! {
#[allow(unused_mut)] #[allow(unused_mut)]
let mut #label #field_type = #default_value; let mut #label #field_type = vec![];
}) })
} }

View File

@ -1,7 +1,5 @@
use crate::{ use super::build_default_value::{build_default_value, build_default_vec_value};
common::{Field, YaSerdeAttribute, YaSerdeField}, use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
de::build_default_value::build_default_value,
};
use proc_macro2::{Span, TokenStream}; use proc_macro2::{Span, TokenStream};
use quote::quote; use quote::quote;
use syn::{DataStruct, Ident}; use syn::{DataStruct, Ident};
@ -24,38 +22,25 @@ pub fn parse(
.iter() .iter()
.map(|field| YaSerdeField::new(field.clone())) .map(|field| YaSerdeField::new(field.clone()))
.filter_map(|field| match field.get_type() { .filter_map(|field| match field.get_type() {
Field::FieldStruct { struct_name } => build_default_value( Field::FieldStruct { struct_name } => build_default_value(&field, Some(quote!(#struct_name))),
&field, Field::FieldOption { .. } => build_default_value(&field, None),
Some(quote!(#struct_name)),
quote!(<#struct_name as ::std::default::Default>::default()),
),
Field::FieldOption { .. } => {
build_default_value(&field, None, quote!(::std::option::Option::None))
}
Field::FieldVec { data_type } => match *data_type { Field::FieldVec { data_type } => match *data_type {
Field::FieldStruct { ref struct_name } => build_default_value( Field::FieldStruct { ref struct_name } => {
&field, build_default_vec_value(&field, Some(quote!(::std::vec::Vec<#struct_name>)))
Some(quote!(::std::vec::Vec<#struct_name>)), }
quote!(::std::vec![]),
),
Field::FieldOption { .. } | Field::FieldVec { .. } => { Field::FieldOption { .. } | Field::FieldVec { .. } => {
unimplemented!("Option or Vec nested in Vec<>"); unimplemented!("Option or Vec nested in Vec<>");
} }
simple_type => { simple_type => {
let type_token: TokenStream = simple_type.into(); let type_token: TokenStream = simple_type.into();
build_default_value( build_default_vec_value(&field, Some(quote!(::std::vec::Vec<#type_token>)))
&field,
Some(quote!(::std::vec::Vec<#type_token>)),
quote!(::std::vec![]),
)
} }
}, },
simple_type => { simple_type => {
let type_token: TokenStream = simple_type.into(); let type_token: TokenStream = simple_type.into();
let value_builder = quote!(<#type_token as ::std::default::Default>::default());
build_default_value(&field, Some(type_token), value_builder) build_default_value(&field, Some(type_token))
} }
}) })
.collect(); .collect();
@ -74,6 +59,9 @@ pub fn parse(
let visitor_label = field.get_visitor_ident(Some(&struct_name)); let visitor_label = field.get_visitor_ident(Some(&struct_name));
let xml_opening = format!("<{struct_id}>");
let xml_closing = format!("</{struct_id}>");
Some(quote! { Some(quote! {
#[allow(non_snake_case, non_camel_case_types)] #[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label; struct #visitor_label;
@ -84,7 +72,7 @@ pub fn parse(
self, self,
v: &str, v: &str,
) -> ::std::result::Result<Self::Value, ::std::string::String> { ) -> ::std::result::Result<Self::Value, ::std::string::String> {
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">"; let content = format!("{}{}{}", #xml_opening, v, #xml_closing);
::yaserde::de::from_str(&content) ::yaserde::de::from_str(&content)
} }
} }
@ -185,12 +173,14 @@ pub fn parse(
}; };
match field.get_type() { match field.get_type() {
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }), Field::FieldStruct { struct_name } => {
visit_struct(struct_name, quote! { = ::std::option::Option::Some(value) })
}
Field::FieldOption { data_type } => { Field::FieldOption { data_type } => {
visit_sub(data_type, quote! { = ::std::option::Option::Some(value) }) visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
} }
Field::FieldVec { data_type } => visit_sub(data_type, quote! { .push(value) }), Field::FieldVec { data_type } => visit_sub(data_type, quote! { .push(value) }),
simple_type => visit_simple(simple_type, quote! { = value }), simple_type => visit_simple(simple_type, quote! { = ::std::option::Option::Some(value) }),
} }
}) })
.collect(); .collect();
@ -205,7 +195,7 @@ pub fn parse(
match field.get_type() { match field.get_type() {
Field::FieldStruct { .. } => quote! { Field::FieldStruct { .. } => quote! {
#value_label = ::yaserde::de::from_str(&unused_xml_elements)?; #value_label = Some(::yaserde::de::from_str(&unused_xml_elements)?);
}, },
Field::FieldOption { data_type } => match *data_type { Field::FieldOption { data_type } => match *data_type {
Field::FieldStruct { .. } => quote! { Field::FieldStruct { .. } => quote! {
@ -258,7 +248,7 @@ pub fn parse(
Some(quote! { Some(quote! {
for attr in attributes { for attr in attributes {
if attr.name.local_name == #label_name { if attr.name.local_name == #label_name {
#label = attr.value.to_owned(); #label = Some(attr.value.to_owned());
} }
} }
}) })
@ -304,8 +294,8 @@ pub fn parse(
&visitor_label, &visitor_label,
), ),
}, },
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }), Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = Some(value) }),
simple_type => visit_simple(simple_type, quote! { = value }), simple_type => visit_simple(simple_type, quote! { = Some(value) }),
} }
}) })
.collect(); .collect();
@ -318,15 +308,13 @@ pub fn parse(
let label = field.get_value_label(); let label = field.get_value_label();
let set_text = |action: &TokenStream| { let set_text = |action: &TokenStream| {
if field.is_text_content() { field
Some(quote! { #label = #action; }) .is_text_content()
} else { .then_some(quote! { #label = #action; })
None
}
}; };
match field.get_type() { match field.get_type() {
Field::FieldString => set_text(&quote! { text_content.to_owned() }), Field::FieldString => set_text(&quote! { Some(text_content.to_owned()) }),
Field::FieldOption { data_type } => match *data_type { Field::FieldOption { data_type } => match *data_type {
Field::FieldString => set_text( Field::FieldString => set_text(
&quote! { if text_content.is_empty() { None } else { Some(text_content.to_owned()) }}, &quote! { if text_content.is_empty() { None } else { Some(text_content.to_owned()) }},
@ -350,7 +338,26 @@ pub fn parse(
let label = &field.label(); let label = &field.label();
let value_label = field.get_value_label(); let value_label = field.get_value_label();
quote! { #label: #value_label, } match field.get_type() {
Field::FieldOption { .. } | Field::FieldVec { .. } => {
quote! { #label: #value_label, }
}
_ => {
if let Some(default_function) = field.get_default_function() {
quote! { #label: #value_label.unwrap_or_else(|| #default_function()), }
} else {
let error = format!(
"{} is a required field",
label
.as_ref()
.map(|label| label.to_string())
.unwrap_or_default()
);
quote! { #label: #value_label.ok_or_else(|| #error.to_string())?, }
}
}
}
}) })
.collect(); .collect();