parent
e4aff84acb
commit
a067b85ee2
@ -10,7 +10,7 @@ use yaserde::*;
|
|||||||
namespace = "html: http://www.w3.org/TR/REC-html40"
|
namespace = "html: http://www.w3.org/TR/REC-html40"
|
||||||
)]
|
)]
|
||||||
struct Workbook {
|
struct Workbook {
|
||||||
#[yaserde(rename = "Worksheet")]
|
#[yaserde(rename = "Worksheet", prefix = "ss")]
|
||||||
worksheet: Worksheet,
|
worksheet: Worksheet,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ struct Workbook {
|
|||||||
namespace = "html: http://www.w3.org/TR/REC-html40"
|
namespace = "html: http://www.w3.org/TR/REC-html40"
|
||||||
)]
|
)]
|
||||||
struct Worksheet {
|
struct Worksheet {
|
||||||
#[yaserde(rename = "Table")]
|
#[yaserde(rename = "Table", prefix = "ss")]
|
||||||
table: Table,
|
table: Table,
|
||||||
#[yaserde(attribute, rename = "Name", prefix = "ss")]
|
#[yaserde(attribute, rename = "Name", prefix = "ss")]
|
||||||
ws_name: String,
|
ws_name: String,
|
||||||
@ -53,7 +53,7 @@ struct Table {
|
|||||||
#[yaserde(attribute, rename = "DefaultRowHeight", prefix = "ss")]
|
#[yaserde(attribute, rename = "DefaultRowHeight", prefix = "ss")]
|
||||||
default_column_height: f32,
|
default_column_height: f32,
|
||||||
|
|
||||||
#[yaserde(rename = "Row")]
|
#[yaserde(rename = "Row", prefix = "ss")]
|
||||||
rows: Vec<Row>,
|
rows: Vec<Row>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
||||||
|
#[yaserde(namespace = "u: urn:schemas-upnp-org:service:AVTransport:1")]
|
||||||
pub struct SoapPlay {
|
pub struct SoapPlay {
|
||||||
#[yaserde(rename = "Play", prefix = "u", default)]
|
#[yaserde(rename = "Play", prefix = "u", default)]
|
||||||
pub body: Play,
|
pub body: Play,
|
||||||
@ -93,6 +94,7 @@ fn test_for_generic_nested_struct() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let s = ser::to_string(&a).unwrap();
|
let s = ser::to_string(&a).unwrap();
|
||||||
|
println!("{s}");
|
||||||
let b: SoapEnvelope<SoapPlay> = de::from_str(&s).unwrap();
|
let b: SoapEnvelope<SoapPlay> = de::from_str(&s).unwrap();
|
||||||
|
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
|
|||||||
@ -2,4 +2,5 @@ mod bbigras_namespace;
|
|||||||
mod boscop;
|
mod boscop;
|
||||||
mod generic;
|
mod generic;
|
||||||
mod ln_dom;
|
mod ln_dom;
|
||||||
|
mod same_element_different_namespaces;
|
||||||
mod svd;
|
mod svd;
|
||||||
|
|||||||
37
examples/src/same_element_different_namespaces.rs
Normal file
37
examples/src/same_element_different_namespaces.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// related to issue https://github.com/media-io/yaserde/issues/186
|
||||||
|
use yaserde::*;
|
||||||
|
|
||||||
|
#[derive(YaDeserialize, Debug, PartialEq)]
|
||||||
|
#[yaserde(
|
||||||
|
namespace = "myns: http://my_namespace_1/",
|
||||||
|
namespace = "ext: http://my_namespace_2/",
|
||||||
|
prefix = "myns"
|
||||||
|
)]
|
||||||
|
pub struct ErrorType {
|
||||||
|
#[yaserde(rename = "reasonCode", prefix = "myns")]
|
||||||
|
pub reason_code: Option<u16>,
|
||||||
|
#[yaserde(rename = "reasonCode", prefix = "ext")]
|
||||||
|
pub ext_reason_code: Option<u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn same_element_different_namespaces() {
|
||||||
|
use yaserde::de::from_str;
|
||||||
|
|
||||||
|
let content = r#"
|
||||||
|
<error_type xmlns="http://my_namespace_1/" xmlns:ext="http://my_namespace_2/">
|
||||||
|
<reasonCode>12</reasonCode>
|
||||||
|
<ext:reasonCode>32</ext:reasonCode>
|
||||||
|
</error_type>
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let loaded: ErrorType = from_str(content).unwrap();
|
||||||
|
println!("{:?}", loaded);
|
||||||
|
|
||||||
|
let reference = ErrorType {
|
||||||
|
reason_code: Some(12),
|
||||||
|
ext_reason_code: Some(32),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(loaded, reference);
|
||||||
|
}
|
||||||
@ -90,6 +90,13 @@ impl YaSerdeField {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let prefix = self
|
||||||
|
.attributes
|
||||||
|
.prefix
|
||||||
|
.clone()
|
||||||
|
.map(|p| format!("{}_", p.to_upper_camel_case()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
let attribute = self
|
let attribute = self
|
||||||
.attributes
|
.attributes
|
||||||
.attribute
|
.attribute
|
||||||
@ -98,7 +105,8 @@ impl YaSerdeField {
|
|||||||
|
|
||||||
Ident::new(
|
Ident::new(
|
||||||
&format!(
|
&format!(
|
||||||
"__Visitor_{attribute}{}_{}",
|
"__Visitor_{attribute}{}{}_{}",
|
||||||
|
prefix,
|
||||||
label.replace('.', "_").to_upper_camel_case(),
|
label.replace('.', "_").to_upper_camel_case(),
|
||||||
struct_id
|
struct_id
|
||||||
),
|
),
|
||||||
@ -130,6 +138,20 @@ impl YaSerdeField {
|
|||||||
.map(|skip_serializing_if| Ident::new(skip_serializing_if, self.get_span()))
|
.map(|skip_serializing_if| Ident::new(skip_serializing_if, self.get_span()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prefix_namespace(&self, root_attributes: &YaSerdeAttribute) -> String {
|
||||||
|
root_attributes
|
||||||
|
.namespaces
|
||||||
|
.iter()
|
||||||
|
.find_map(|(prefix, namespace)| {
|
||||||
|
if self.attributes.prefix.eq(prefix) {
|
||||||
|
Some(namespace.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_namespace_matching(
|
pub fn get_namespace_matching(
|
||||||
&self,
|
&self,
|
||||||
root_attributes: &YaSerdeAttribute,
|
root_attributes: &YaSerdeAttribute,
|
||||||
@ -261,7 +283,7 @@ impl From<&syn::PathSegment> for Field {
|
|||||||
return Field::from(&path.path);
|
return Field::from(&path.path);
|
||||||
}
|
}
|
||||||
Some(syn::GenericArgument::Type(syn::Type::Group(syn::TypeGroup { elem, .. }))) => {
|
Some(syn::GenericArgument::Type(syn::Type::Group(syn::TypeGroup { elem, .. }))) => {
|
||||||
if let syn::Type::Path(ref group) = elem.as_ref() {
|
if let Path(ref group) = elem.as_ref() {
|
||||||
return Field::from(&group.path);
|
return Field::from(&group.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,9 +148,11 @@ pub fn parse(
|
|||||||
let value_label = field.get_value_label();
|
let value_label = field.get_value_label();
|
||||||
let label_name = field.renamed_label_without_namespace();
|
let label_name = field.renamed_label_without_namespace();
|
||||||
|
|
||||||
|
let namespace = field.prefix_namespace(root_attributes);
|
||||||
|
|
||||||
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
#label_name => {
|
(#namespace, #label_name) => {
|
||||||
if depth == 0 {
|
if depth == 0 {
|
||||||
// Don't count current struct's StartElement as substruct's StartElement
|
// Don't count current struct's StartElement as substruct's StartElement
|
||||||
let _root = reader.next_event();
|
let _root = reader.next_event();
|
||||||
@ -423,7 +425,9 @@ pub fn parse(
|
|||||||
let event = reader.next_event()?;
|
let event = reader.next_event()?;
|
||||||
#write_unused
|
#write_unused
|
||||||
} else {
|
} else {
|
||||||
match name.local_name.as_str() {
|
let namespace = name.namespace.clone().unwrap_or_default();
|
||||||
|
|
||||||
|
match (namespace.as_str(), name.local_name.as_str()) {
|
||||||
#call_visitors
|
#call_visitors
|
||||||
_ => {
|
_ => {
|
||||||
let event = reader.next_event()?;
|
let event = reader.next_event()?;
|
||||||
@ -493,8 +497,10 @@ fn build_call_visitor(
|
|||||||
quote!(name.local_name.as_str()),
|
quote!(name.local_name.as_str()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let namespace = field.prefix_namespace(root_attributes);
|
||||||
|
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
#label_name => {
|
(#namespace, #label_name) => {
|
||||||
let visitor = #visitor_label{};
|
let visitor = #visitor_label{};
|
||||||
|
|
||||||
#namespaces_matching
|
#namespaces_matching
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user