diff --git a/yaserde/tests/deserializer.rs b/yaserde/tests/deserializer.rs
index 53489f2..fcf7cb8 100644
--- a/yaserde/tests/deserializer.rs
+++ b/yaserde/tests/deserializer.rs
@@ -9,10 +9,10 @@ use xml::reader::EventReader;
use yaserde::YaDeserialize;
macro_rules! convert_and_validate {
- ($content:expr, $model:expr) => {
+ ($content:expr, $struct:tt, $model:expr) => {
let mut parser = EventReader::from_str($content);
- let loaded = XmlStruct::derive_deserialize(&mut parser, None);
+ let loaded = $struct::derive_deserialize(&mut parser, None);
assert_eq!(loaded, Ok($model));
}
}
@@ -26,7 +26,7 @@ fn de_basic() {
}
let content = "- something
";
- convert_and_validate!(content, XmlStruct{
+ convert_and_validate!(content, XmlStruct, XmlStruct{
item: "something".to_string()
});
}
@@ -40,12 +40,37 @@ fn de_list_of_items() {
}
let content = "something1something2";
- convert_and_validate!(content, XmlStruct{
+ convert_and_validate!(content, XmlStruct, XmlStruct{
items: vec![
"something1".to_string(),
"something2".to_string()
]
});
+
+ #[derive(YaDeserialize, PartialEq, Debug)]
+ #[yaserde(root="base")]
+ pub struct XmlStructOfStruct {
+ items: Vec
+ }
+
+
+ #[derive(YaDeserialize, PartialEq, Debug)]
+ #[yaserde(root="items")]
+ pub struct SubStruct {
+ field: String
+ }
+
+ let content = "something1something2";
+ convert_and_validate!(content, XmlStructOfStruct, XmlStructOfStruct{
+ items: vec![
+ SubStruct{
+ field: "something1".to_string()
+ },
+ SubStruct{
+ field: "something2".to_string()
+ }
+ ]
+ });
}
#[test]
@@ -74,7 +99,7 @@ fn de_attributes() {
}
let content = "";
- convert_and_validate!(content, XmlStruct{
+ convert_and_validate!(content, XmlStruct, XmlStruct{
item: "something".to_string(),
sub: SubStruct{
subitem: "sub-something".to_string()
@@ -109,7 +134,7 @@ fn de_rename() {
}
let content = "";
- convert_and_validate!(content, XmlStruct{
+ convert_and_validate!(content, XmlStruct, XmlStruct{
item: "something".to_string(),
sub_struct: SubStruct{
subitem: "sub_something".to_string()
@@ -147,7 +172,7 @@ fn de_text_content_with_attributes() {
}
let content = "text_content";
- convert_and_validate!(content, XmlStruct{
+ convert_and_validate!(content, XmlStruct, XmlStruct{
item: "something".to_string(),
sub_struct: SubStruct{
subitem: "sub_something".to_string(),
diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs
index 8424f8c..e1f9090 100644
--- a/yaserde/tests/serializer.rs
+++ b/yaserde/tests/serializer.rs
@@ -57,6 +57,34 @@ fn ser_list_of_items() {
let content = "something1something2".to_string();
convert_and_validate!(model, content);
+
+
+ #[derive(YaSerialize, PartialEq, Debug)]
+ #[yaserde(root="base")]
+ pub struct XmlStructOfStruct {
+ items: Vec
+ }
+
+
+ #[derive(YaSerialize, PartialEq, Debug)]
+ #[yaserde(root="items")]
+ pub struct SubStruct {
+ field: String
+ }
+
+ let model2 = XmlStructOfStruct{
+ items: vec![
+ SubStruct{
+ field: "something1".to_string()
+ },
+ SubStruct{
+ field: "something2".to_string()
+ }
+ ]
+ };
+
+ let content = "something1something2";
+ convert_and_validate!(model2, content);
}
#[test]
diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs
index fbe6593..93b103a 100644
--- a/yaserde_derive/src/de/expand_struct.rs
+++ b/yaserde_derive/src/de/expand_struct.rs
@@ -16,16 +16,28 @@ pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String) -> Tokens {
let mut #label : String = "".to_string();
})
},
- Some(FieldType::FieldTypeVec{data_type}) => {
- Some(quote!{
- let mut #label : Vec<#data_type> = vec![];
- })
- },
Some(FieldType::FieldTypeStruct{struct_name}) => {
Some(quote!{
let mut #label : #struct_name = #struct_name::default();
})
- }
+ },
+ Some(FieldType::FieldTypeVec{data_type}) => {
+ let dt = Box::into_raw(data_type);
+ match unsafe{dt.as_ref()} {
+ Some(&FieldType::FieldTypeString) => {
+ Some(quote!{
+ let mut #label : Vec = vec![];
+ })
+ },
+ Some(&FieldType::FieldTypeStruct{struct_name}) => {
+ Some(quote!{
+ let mut #label : Vec<#struct_name> = vec![];
+ })
+ },
+ Some(&FieldType::FieldTypeVec{..}) => {unimplemented!();},
+ None => {unimplemented!();},
+ }
+ },
_ => None
}
})
@@ -144,8 +156,9 @@ pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String) -> Tokens {
})
},
Some(FieldType::FieldTypeVec{data_type}) => {
- match data_type.to_string().as_str() {
- "String" => {
+ let dt = Box::into_raw(data_type);
+ match unsafe{dt.as_ref()} {
+ Some(&FieldType::FieldTypeString) => {
Some(quote!{
#label_name => {
match read.next() {
@@ -157,7 +170,7 @@ pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String) -> Tokens {
},
})
},
- struct_name => {
+ Some(&FieldType::FieldTypeStruct{struct_name}) => {
let struct_ident = Ident::new(&format!("{}", struct_name), Span::def_site());
Some(quote!{
#label_name => {
@@ -172,7 +185,9 @@ pub fn parse(data_struct: &DataStruct, name: &Ident, root: &String) -> Tokens {
}
},
})
- }
+ },
+ Some(&FieldType::FieldTypeVec{..}) => {unimplemented!();},
+ None => {unimplemented!();},
}
},
_ => None
diff --git a/yaserde_derive/src/field_type.rs b/yaserde_derive/src/field_type.rs
index 4c694a6..5b9601c 100644
--- a/yaserde_derive/src/field_type.rs
+++ b/yaserde_derive/src/field_type.rs
@@ -6,38 +6,47 @@ use syn::Type::Path;
#[derive(Debug)]
pub enum FieldType {
FieldTypeString,
- FieldTypeVec{data_type: syn::Ident},
+ FieldTypeVec{data_type: Box},
FieldTypeStruct{struct_name: syn::Ident},
}
+impl FieldType {
+ fn from_ident(t: &syn::PathSegment) -> Option {
+ match t.ident.as_ref() {
+ "String" => Some(FieldType::FieldTypeString),
+ "Vec" => {
+ get_vec_type(t).map(|data_type| {
+ let p = syn::PathSegment{
+ ident: data_type,
+ arguments: syn::PathArguments::None
+ };
+
+ FieldType::FieldTypeVec{
+ data_type: Box::new(FieldType::from_ident(&p).unwrap())
+ }
+ })
+ },
+ _struct_name =>
+ Some(FieldType::FieldTypeStruct{
+ struct_name: t.ident
+ }),
+ }
+ }
+}
+
pub fn get_field_type(field: &syn::Field) -> Option {
match field.ty {
Path(ref path) => {
match path.path.segments.first() {
Some(Pair::End(t)) => {
- match t.ident.to_string().as_str() {
- "String" => Some(FieldType::FieldTypeString),
- "Vec" => {
- match get_vec_type(t) {
- Some(data_type) =>
- Some(FieldType::FieldTypeVec{
- data_type: data_type
- }),
- None => None,
- }
- },
- _struct_name =>
- Some(FieldType::FieldTypeStruct{
- struct_name: t.ident
- }),
- }
+ FieldType::from_ident(t)
},
_ => {
None
},
}
},
- _ => {None},
+ _ => None,
}
}
diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs
index 7d913aa..bb50aa5 100644
--- a/yaserde_derive/src/ser/expand_struct.rs
+++ b/yaserde_derive/src/ser/expand_struct.rs
@@ -75,19 +75,39 @@ pub fn serialize(data_struct: &DataStruct, name: &Ident, root: &String) -> Token
},
};
}),
- Some(FieldType::FieldTypeVec{..}) =>
- Some(quote!{
- for item in &self.#label {
- let start_event = XmlEvent::start_element(#label_name);
- let _ret = writer.write(start_event);
+ Some(FieldType::FieldTypeVec{data_type}) => {
+ let dt = Box::into_raw(data_type);
+ match unsafe{dt.as_ref()} {
+ Some(&FieldType::FieldTypeString) => {
+ Some(quote!{
+ for item in &self.#label {
+ let start_event = XmlEvent::start_element(#label_name);
+ let _ret = writer.write(start_event);
- let data_event = XmlEvent::characters(item);
- let _ret = writer.write(data_event);
+ let data_event = XmlEvent::characters(item);
+ let _ret = writer.write(data_event);
- let end_event = XmlEvent::end_element();
- let _ret = writer.write(end_event);
- }
- }),
+ let end_event = XmlEvent::end_element();
+ let _ret = writer.write(end_event);
+ }
+ })
+ },
+ Some(&FieldType::FieldTypeStruct{..}) => {
+ Some(quote!{
+ for item in &self.#label {
+ match item.derive_serialize(writer) {
+ Ok(()) => {},
+ Err(msg) => {
+ return Err(msg);
+ },
+ };
+ }
+ })
+ },
+ Some(&FieldType::FieldTypeVec{..}) => {unimplemented!();},
+ None => {unimplemented!();},
+ }
+ },
None => None,
}
})