be able to use Option of struct and String
This commit is contained in:
		
							parent
							
								
									d90c14c2b8
								
							
						
					
					
						commit
						461b30b03c
					
				| @ -42,6 +42,7 @@ pub fn serialize_with_writer_content<W: Write, T: YaSerialize>( | |||||||
| pub struct Serializer<W: Write> { | pub struct Serializer<W: Write> { | ||||||
|   writer: EventWriter<W>, |   writer: EventWriter<W>, | ||||||
|   skip_start_end: bool, |   skip_start_end: bool, | ||||||
|  |   start_event_name: Option<String>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'de, W: Write> Serializer<W> { | impl<'de, W: Write> Serializer<W> { | ||||||
| @ -49,6 +50,7 @@ impl<'de, W: Write> Serializer<W> { | |||||||
|     Serializer { |     Serializer { | ||||||
|       writer, |       writer, | ||||||
|       skip_start_end: false, |       skip_start_end: false, | ||||||
|  |       start_event_name: None, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -76,6 +78,14 @@ impl<'de, W: Write> Serializer<W> { | |||||||
|     self.skip_start_end = state; |     self.skip_start_end = state; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   pub fn get_start_event_name<'a>(&self) -> Option<String> { | ||||||
|  |     self.start_event_name.clone() | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   pub fn set_start_event_name<'a>(&mut self, name: Option<String>) { | ||||||
|  |     self.start_event_name = name; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   pub fn write<'a, E>(&mut self, event: E) -> xml::writer::Result<()> |   pub fn write<'a, E>(&mut self, event: E) -> xml::writer::Result<()> | ||||||
|   where |   where | ||||||
|     E: Into<XmlEvent<'a>>, |     E: Into<XmlEvent<'a>>, | ||||||
|  | |||||||
| @ -116,3 +116,27 @@ fn de_option() { | |||||||
|   convert_and_validate_for_attribute!(f64, Some(-12.5 as f64), Some("-12.5")); |   convert_and_validate_for_attribute!(f64, Some(-12.5 as f64), Some("-12.5")); | ||||||
|   convert_and_validate_for_attribute!(f64, None, None); |   convert_and_validate_for_attribute!(f64, None, None); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn de_option_struct() { | ||||||
|  |   #[derive(YaDeserialize, Debug, PartialEq)] | ||||||
|  |   struct Test { | ||||||
|  |     field: SubTest | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #[derive(YaDeserialize, Debug, PartialEq)] | ||||||
|  |   struct SubTest { | ||||||
|  |     content: Option<String> | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   impl Default for SubTest { | ||||||
|  |     fn default() -> Self { | ||||||
|  |       SubTest { | ||||||
|  |         content: None | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   convert_and_validate!(Test, Some(Test{field: SubTest{content: Some("value".to_string())}}), Some("<Test><field><content>value</content></field></Test>")); | ||||||
|  |   convert_and_validate!(Test, None, None); | ||||||
|  | } | ||||||
|  | |||||||
| @ -119,3 +119,27 @@ fn ser_option() { | |||||||
|   convert_and_validate_as_attribute!(f64, Some(-12.5 as f64), Some("-12.5")); |   convert_and_validate_as_attribute!(f64, Some(-12.5 as f64), Some("-12.5")); | ||||||
|   convert_and_validate_as_attribute!(f64, None, None); |   convert_and_validate_as_attribute!(f64, None, None); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn de_option_struct() { | ||||||
|  |   #[derive(YaSerialize, Debug, PartialEq)] | ||||||
|  |   struct Test { | ||||||
|  |     field: SubTest | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #[derive(YaSerialize, Debug, PartialEq)] | ||||||
|  |   struct SubTest { | ||||||
|  |     content: Option<String> | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   impl Default for SubTest { | ||||||
|  |     fn default() -> Self { | ||||||
|  |       SubTest { | ||||||
|  |         content: None | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   convert_and_validate!(Test, Some(Test{field: SubTest{content: Some("value".to_string())}}), Some("<Test><field><content>value</content></field></Test>")); | ||||||
|  |   convert_and_validate!(Test, None, None); | ||||||
|  | } | ||||||
|  | |||||||
| @ -273,7 +273,7 @@ fn ser_enum() { | |||||||
|     }, |     }, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><custom><enabled>true</enabled><color><red>0</red><green>128</green><blue>255</blue></color><alpha>Opaque</alpha><alphas>Opaque</alphas><alphas>Transparent</alphas></custom></color></base>"; |   let content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><base><color><enabled>true</enabled><color><red>0</red><green>128</green><blue>255</blue></color><alpha>Opaque</alpha><alphas>Opaque</alphas><alphas>Transparent</alphas></color></base>"; | ||||||
|   convert_and_validate!(model, content); |   convert_and_validate!(model, content); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -234,7 +234,18 @@ pub fn parse( | |||||||
|             Some(&FieldType::FieldTypeF64) => { |             Some(&FieldType::FieldTypeF64) => { | ||||||
|               build_declare_visitor("e!{f64}, "e!{visit_f64}, &visitor_label) |               build_declare_visitor("e!{f64}, "e!{visit_f64}, &visitor_label) | ||||||
|             } |             } | ||||||
|             _ => { |             Some(&FieldType::FieldTypeStruct{ref struct_name}) => { | ||||||
|  |               let struct_ident = Ident::new(&format!("{}", struct_name), Span::call_site()); | ||||||
|  |               Some(quote!{ | ||||||
|  |                 #[allow(non_snake_case, non_camel_case_types)] | ||||||
|  |                 struct #visitor_label; | ||||||
|  |                 impl<'de> Visitor<'de> for #visitor_label { | ||||||
|  |                   type Value = #struct_ident; | ||||||
|  |                 } | ||||||
|  |               }) | ||||||
|  |             } | ||||||
|  |             dude => { | ||||||
|  |               println!("{:?}", dude); | ||||||
|               unimplemented!(); |               unimplemented!(); | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
| @ -602,7 +613,24 @@ pub fn parse( | |||||||
|                 &label_name, |                 &label_name, | ||||||
|               ) |               ) | ||||||
|             } |             } | ||||||
|             _ => None, |             Some(&FieldType::FieldTypeStruct { ref struct_name }) => { | ||||||
|  |               let struct_ident = Ident::new(&format!("{}", struct_name), Span::call_site()); | ||||||
|  |               Some(quote!{ | ||||||
|  |                 #label_name => { | ||||||
|  |                   reader.set_map_value(); | ||||||
|  |                   match #struct_ident::deserialize(reader) { | ||||||
|  |                     Ok(parsed_item) => { | ||||||
|  |                       #label = Some(parsed_item); | ||||||
|  |                       let _root = reader.next_event(); | ||||||
|  |                     }, | ||||||
|  |                     Err(msg) => { | ||||||
|  |                       return Err(msg); | ||||||
|  |                     }, | ||||||
|  |                   } | ||||||
|  |                 } | ||||||
|  |               }) | ||||||
|  |             } | ||||||
|  |             _ => unimplemented!(), | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         Some(FieldType::FieldTypeVec { data_type }) => { |         Some(FieldType::FieldTypeVec { data_type }) => { | ||||||
|  | |||||||
| @ -123,13 +123,7 @@ pub fn serialize( | |||||||
| 
 | 
 | ||||||
|           Some(quote!{ |           Some(quote!{ | ||||||
|             &#name::#label{..} => { |             &#name::#label{..} => { | ||||||
|               let struct_start_event = XmlEvent::start_element(#label_name); |  | ||||||
|               let _ret = writer.write(struct_start_event); |  | ||||||
| 
 |  | ||||||
|               #enum_fields |               #enum_fields | ||||||
| 
 |  | ||||||
|               let struct_end_event = XmlEvent::end_element(); |  | ||||||
|               let _ret = writer.write(struct_end_event); |  | ||||||
|             } |             } | ||||||
|           }) |           }) | ||||||
|         } |         } | ||||||
| @ -164,6 +158,11 @@ pub fn serialize( | |||||||
|       #[allow(unused_variables)] |       #[allow(unused_variables)] | ||||||
|       fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) |       fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) | ||||||
|         -> Result<(), String> { |         -> Result<(), String> { | ||||||
|  |         if let Some(label) = writer.get_start_event_name() { | ||||||
|  |           let struct_start_event = XmlEvent::start_element(label.as_ref()); | ||||||
|  |           let _ret = writer.write(struct_start_event); | ||||||
|  |           return Ok(()); | ||||||
|  |         } | ||||||
|         error!("Enum: start to expand {:?}", #root); |         error!("Enum: start to expand {:?}", #root); | ||||||
| 
 | 
 | ||||||
|         if !writer.skip_start_end() { |         if !writer.skip_start_end() { | ||||||
|  | |||||||
| @ -105,7 +105,7 @@ pub fn serialize( | |||||||
|                 let _ret = writer.write(end_event); |                 let _ret = writer.write(end_event); | ||||||
|               } |               } | ||||||
|             }), |             }), | ||||||
|             _ => None, |             _ => unimplemented!(), | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{ |         Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{ | ||||||
| @ -170,7 +170,7 @@ pub fn serialize( | |||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       let label_name = if let Some(prefix) = field_attrs.prefix { |       let label_name = if let Some(prefix) = field_attrs.prefix { | ||||||
|         prefix + ":" + renamed_label.to_string().as_ref() |         format!("{}:{}", prefix, renamed_label) | ||||||
|       } else { |       } else { | ||||||
|         renamed_label.to_string() |         renamed_label.to_string() | ||||||
|       }; |       }; | ||||||
| @ -260,17 +260,46 @@ pub fn serialize( | |||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|             }), |             }), | ||||||
|             _ => None, |             Some(&FieldType::FieldTypeStruct { .. }) => Some(quote!{ | ||||||
|  |               if let Some(ref item) = &self.#label { | ||||||
|  |                 let start_event = XmlEvent::start_element(#label_name); | ||||||
|  |                 let _ret = writer.write(start_event); | ||||||
|  | 
 | ||||||
|  |                 writer.set_skip_start_end(false); | ||||||
|  |                 match item.serialize(writer) { | ||||||
|  |                   Ok(()) => {}, | ||||||
|  |                   Err(msg) => { | ||||||
|  |                     return Err(msg); | ||||||
|  |                   }, | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 let end_event = XmlEvent::end_element(); | ||||||
|  |                 let _ret = writer.write(end_event); | ||||||
|  |               } | ||||||
|  |             }), | ||||||
|  |             _ => unimplemented!(), | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{ |         Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{ | ||||||
|           writer.set_skip_start_end(false); |           writer.set_start_event_name(Some(#label_name.to_string())); | ||||||
|           match self.#label.serialize(writer) { |           match self.#label.serialize(writer) { | ||||||
|             Ok(()) => {}, |             Ok(()) => {}, | ||||||
|             Err(msg) => { |             Err(msg) => { | ||||||
|               return Err(msg); |               return Err(msg); | ||||||
|             }, |             }, | ||||||
|           }; |           }; | ||||||
|  |           writer.set_start_event_name(None); | ||||||
|  | 
 | ||||||
|  |           writer.set_skip_start_end(true); | ||||||
|  |           match self.#label.serialize(writer) { | ||||||
|  |             Ok(()) => {}, | ||||||
|  |             Err(msg) => { | ||||||
|  |               return Err(msg); | ||||||
|  |             }, | ||||||
|  |           }; | ||||||
|  | 
 | ||||||
|  |           let end_event = XmlEvent::end_element(); | ||||||
|  |           let _ret = writer.write(end_event); | ||||||
|         }), |         }), | ||||||
|         Some(FieldType::FieldTypeVec { data_type }) => { |         Some(FieldType::FieldTypeVec { data_type }) => { | ||||||
|           let dt = Box::into_raw(data_type); |           let dt = Box::into_raw(data_type); | ||||||
| @ -358,6 +387,12 @@ pub fn serialize( | |||||||
|       #[allow(unused_variables)] |       #[allow(unused_variables)] | ||||||
|       fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) |       fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) | ||||||
|         -> Result<(), String> { |         -> Result<(), String> { | ||||||
|  |         if let Some(label) = writer.get_start_event_name() { | ||||||
|  |           let struct_start_event = XmlEvent::start_element(label.as_ref()); | ||||||
|  |           #build_attributes | ||||||
|  |           let _ret = writer.write(struct_start_event); | ||||||
|  |           return Ok(()) | ||||||
|  |         } | ||||||
|         error!("Struct: start to expand {:?}", #root); |         error!("Struct: start to expand {:?}", #root); | ||||||
|         let skip = writer.skip_start_end(); |         let skip = writer.skip_start_end(); | ||||||
|         if !skip { |         if !skip { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user