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