Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/src/bbigras_namespace.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(dead_code)]
// related to issue https://github.com/media-io/yaserde/issues/15
use yaserde::*;

Expand Down
1 change: 1 addition & 0 deletions examples/src/boscop.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(dead_code)]
// related to issue https://github.com/media-io/yaserde/issues/3
use yaserde::*;

Expand Down
1 change: 1 addition & 0 deletions examples/src/generic.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(dead_code)]
use yaserde::*;

#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
Expand Down
1 change: 1 addition & 0 deletions examples/src/ln_dom.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(dead_code)]
// related to issue https://github.com/media-io/yaserde/issues/11
use yaserde::*;

Expand Down
1 change: 1 addition & 0 deletions examples/src/same_element_different_namespaces.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(dead_code)]
// related to issue https://github.com/media-io/yaserde/issues/186
use yaserde::*;

Expand Down
2 changes: 1 addition & 1 deletion examples/tests/data/svd.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<device schemaversion="foo" xmlns="http://www.w3.org/2001/XMLSchema-instance" xsnonamespaceschemalocation="CMSIS-SVD.xsd">
<devattributes>
<vendor>Renesas</vendor>
Expand Down
2 changes: 1 addition & 1 deletion yaserde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ macro_rules! serialize_and_validate {
log::debug!("serialize_and_validate @ {}:{}", file!(), line!());
let data: Result<String, String> = yaserde::ser::to_string(&$model);

let content = &format!(r#"<?xml version="1.0" encoding="utf-8"?>{}"#, $content);
let content = &format!(r#"<?xml version="1.0" encoding="UTF-8"?>{}"#, $content);
assert_eq!(
data,
Ok(content.split("\n").map(|s| s.trim()).collect::<String>())
Expand Down
2 changes: 1 addition & 1 deletion yaserde/tests/cdata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn test_cdata_serialization() {
msgdata: "<tag>Some unescaped content</tag>".to_string(),
};
let xml_output = yaserde::ser::to_string(&test_data).expect("Serialization failed");
let expected_output = r#"<?xml version="1.0" encoding="utf-8"?><teststruct><msgdata><![CDATA[<tag>Some unescaped content</tag>]]></msgdata></teststruct>"#;
let expected_output = r#"<?xml version="1.0" encoding="UTF-8"?><teststruct><msgdata><![CDATA[<tag>Some unescaped content</tag>]]></msgdata></teststruct>"#;
assert_eq!(xml_output, expected_output);
}

Expand Down
72 changes: 72 additions & 0 deletions yaserde/tests/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ fn de_enum() {
Black,
}

#[allow(dead_code)]
#[derive(YaDeserialize, PartialEq, Debug)]
pub struct RGBColor {
red: String,
Expand Down Expand Up @@ -1101,13 +1102,84 @@ fn de_attribute_sequence() {
deserialize_and_validate!(content, model, Outer);
}

#[test]
fn de_option_vec_as_attribute() {
init();

#[derive(YaDeserialize, PartialEq, Debug)]
#[yaserde(rename = "TestTag")]
pub struct OptionVecAttributeStruct {
#[yaserde(attribute = true)]
field: Option<Vec<u32>>,
}

// Test case 1: Some(populated_vec) -> field="1 2 3 4"
let content = r#"<TestTag field="1 2 3 4" />"#;
let model = OptionVecAttributeStruct {
field: Some(vec![1, 2, 3, 4]),
};
convert_and_validate!(content, OptionVecAttributeStruct, model);

// Test case 2: Some(empty_vec) -> field=""
let content = r#"<TestTag field="" />"#;
let model = OptionVecAttributeStruct {
field: Some(vec![]),
};
convert_and_validate!(content, OptionVecAttributeStruct, model);

// Test case 3: None -> no attribute
let content = r#"<TestTag />"#;
let model = OptionVecAttributeStruct { field: None };
convert_and_validate!(content, OptionVecAttributeStruct, model);
}

#[test]
fn de_option_vec_enum_as_attribute() {
init();

#[derive(YaDeserialize, PartialEq, Debug, Default)]
enum MyEnum {
#[default]
One,
Two,
Three,
}

#[derive(YaDeserialize, PartialEq, Debug)]
#[yaserde(rename = "TestTag")]
pub struct OptionVecEnumAttributeStruct {
#[yaserde(attribute = true)]
field: Option<Vec<MyEnum>>,
}

// Test case 1: Some(vec![MyEnum::One, MyEnum::Two, MyEnum::Three]) -> field="One Two Three"
let content = r#"<TestTag field="One Two Three" />"#;
let model = OptionVecEnumAttributeStruct {
field: Some(vec![MyEnum::One, MyEnum::Two, MyEnum::Three]),
};
convert_and_validate!(content, OptionVecEnumAttributeStruct, model);

// Test case 2: Some(empty_vec) -> field=""
let content = r#"<TestTag field="" />"#;
let model = OptionVecEnumAttributeStruct {
field: Some(vec![]),
};
convert_and_validate!(content, OptionVecEnumAttributeStruct, model);

// Test case 3: None -> no attribute
let content = r#"<TestTag />"#;
let model = OptionVecEnumAttributeStruct { field: None };
convert_and_validate!(content, OptionVecEnumAttributeStruct, model);
}

#[test]
fn de_nested_macro_rules() {
init();

macro_rules! float_attrs {
($type:ty) => {
#[derive(PartialEq, Debug, YaDeserialize)]
#[allow(dead_code)]
pub struct Outer {
#[yaserde(attribute = true)]
pub inner: Option<$type>,
Expand Down
135 changes: 135 additions & 0 deletions yaserde/tests/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,3 +415,138 @@ fn ser_custom() {
let content = "<Date><Year>2020</Year><Month>1</Month><DoubleDay>10</DoubleDay></Date>";
serialize_and_validate!(model, content);
}

#[test]
fn ser_vec_as_attribute() {
#[derive(YaSerialize, PartialEq, Debug)]
#[yaserde(rename = "TestTag")]
pub struct VecAttributeStruct {
#[yaserde(attribute = true)]
numbers: Vec<u32>,
#[yaserde(attribute = true)]
strings: Vec<String>,
#[yaserde(attribute = true)]
bools: Vec<bool>,
#[yaserde(attribute = true)]
floats: Vec<f64>,
}

let model = VecAttributeStruct {
numbers: vec![1, 2, 3, 4],
strings: vec!["hello".to_string(), "world".to_string()],
bools: vec![true, false, true],
floats: vec![6.14, 2.71],
};

// Expected XML with space-separated attribute values
let content = r#"<TestTag numbers="1 2 3 4" strings="hello world" bools="true false true" floats="6.14 2.71" />"#;
serialize_and_validate!(model, content);
}

#[test]
fn ser_vec_as_attribute_nested() {
#[derive(YaSerialize, PartialEq, Debug)]
#[yaserde(rename = "TestTag")]
struct VecAttributeStruct {
#[yaserde(attribute = true)]
outer: Vec<Inner>,
}

#[derive(YaSerialize, PartialEq, Debug)]
#[yaserde(rename = "TestTag")]
enum Inner {
One,
Two,
}

let model = VecAttributeStruct {
outer: vec![Inner::One, Inner::Two],
};

// Expected XML with space-separated attribute values
let content = r#"<TestTag outer="One Two" />"#;
serialize_and_validate!(model, content);
}

#[test]
fn ser_option_vec_as_attribute() {
#[derive(YaSerialize, PartialEq, Debug)]
#[yaserde(rename = "TestTag")]
pub struct OptionVecAttributeStruct {
#[yaserde(attribute = true)]
field: Option<Vec<u32>>,
}

// Expected XML with space-separated attribute values
let model = OptionVecAttributeStruct {
field: Some(vec![1, 2, 3, 4]),
};
let content = r#"<TestTag field="1 2 3 4" />"#;
serialize_and_validate!(model, content);

let model = OptionVecAttributeStruct {
field: Some(vec![]),
};
let content = r#"<TestTag field="" />"#;
serialize_and_validate!(model, content);

// Expected XML with no attributes
let model = OptionVecAttributeStruct { field: None };
let content = r#"<TestTag />"#;
serialize_and_validate!(model, content);
}

#[test]
fn ser_option_vec_complex() {
#[derive(Default, PartialEq, Debug, YaSerialize)]
pub struct Start {
#[yaserde(attribute = true, rename = "value")]
pub value: String,
}

#[derive(Default, PartialEq, Debug, YaSerialize)]
#[yaserde(rename = "String")]
pub struct StringStruct {
#[yaserde(rename = "Start")]
pub start: Option<Vec<Start>>,
}

// Test serialization with Some(vec)
let model = StringStruct {
start: Some(vec![
Start {
value: "First string".to_string(),
},
Start {
value: "Second string".to_string(),
},
Start {
value: "Third string".to_string(),
},
]),
};

let content = yaserde::ser::to_string(&model).unwrap();
assert_eq!(
content,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><String><Start value=\"First string\" /><Start value=\"Second string\" /><Start value=\"Third string\" /></String>"
);

// Test serialization with None
let model_none = StringStruct { start: None };
let content_none = yaserde::ser::to_string(&model_none).unwrap();
assert_eq!(
content_none,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><String />"
);

// Test serialization with Some(empty_vec)
let model_empty = StringStruct {
start: Some(vec![]),
};
let content_empty = yaserde::ser::to_string(&model_empty).unwrap();
assert_eq!(
content_empty,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><String />"
);
}
10 changes: 5 additions & 5 deletions yaserde_derive/src/common/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ impl YaSerdeField {
.map(|p| format!("{}_", p.to_upper_camel_case()))
.unwrap_or_default();

let attribute = self
.attributes
.attribute
.then_some("Attribute_".to_string())
.unwrap_or_default();
let attribute = if self.attributes.attribute {
"Attribute_"
} else {
Default::default()
};

Ident::new(
&format!(
Expand Down
Loading
Loading