From 96bac71db5644a2fa719eec7d492e40432c0d1e1 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Mon, 5 Nov 2018 17:02:37 +0100 Subject: [PATCH] serialize Vec and Option fix #5 --- yaserde/tests/se_option.rs | 5 ++ yaserde/tests/se_type.rs | 10 +++- yaserde_derive/src/field_type.rs | 36 +++++++------ yaserde_derive/src/ser/expand_struct.rs | 67 ++++++++++++++++++------- 4 files changed, 79 insertions(+), 39 deletions(-) diff --git a/yaserde/tests/se_option.rs b/yaserde/tests/se_option.rs index f177b20..6f2f638 100644 --- a/yaserde/tests/se_option.rs +++ b/yaserde/tests/se_option.rs @@ -85,6 +85,11 @@ fn ser_option() { convert_and_validate!(f64, Some(-12.5 as f64), Some("-12.5")); convert_and_validate!(f64, None, None); + convert_and_validate!(Vec, None, None); + convert_and_validate!(Vec, Some(vec![0]), Some("0")); + convert_and_validate!(Vec, None, None); + convert_and_validate!(Vec, Some(vec!["test".to_string()]), Some("test")); + convert_and_validate_as_attribute!(String, Some("test".to_string()), Some("test")); convert_and_validate_as_attribute!(String, None, None); convert_and_validate_as_attribute!(bool, Some(true), Some("true")); diff --git a/yaserde/tests/se_type.rs b/yaserde/tests/se_type.rs index cce650a..d44cf7a 100644 --- a/yaserde/tests/se_type.rs +++ b/yaserde/tests/se_type.rs @@ -19,8 +19,12 @@ macro_rules! convert_and_validate { let model = Data { item: $value }; let data: Result = to_string(&model); - let content = String::from("") + $content - + ""; + let content = if $content == "" { + String::from("") + } else { + String::from("") + $content + + "" + }; assert_eq!(data, Ok(content)); }}; } @@ -60,6 +64,8 @@ fn ser_type() { convert_and_validate!(i64, -12 as i64, "-12"); convert_and_validate!(f32, -12.5 as f32, "-12.5"); convert_and_validate!(f64, -12.5 as f64, "-12.5"); + convert_and_validate!(Vec, vec![], ""); + convert_and_validate!(Vec, vec!["test".to_string()], "test"); convert_and_validate_as_attribute!(String, "test".to_string(), "test"); convert_and_validate_as_attribute!(bool, true, "true"); diff --git a/yaserde_derive/src/field_type.rs b/yaserde_derive/src/field_type.rs index f50a13a..0fec2a9 100644 --- a/yaserde_derive/src/field_type.rs +++ b/yaserde_derive/src/field_type.rs @@ -37,49 +37,47 @@ impl FieldType { "f32" => Some(FieldType::FieldTypeF32), "f64" => Some(FieldType::FieldTypeF64), "Option" => get_sub_type(t).map(|data_type| { - let p = syn::PathSegment { - ident: data_type, - arguments: syn::PathArguments::None, - }; - FieldType::FieldTypeOption { - data_type: Box::new(FieldType::from_ident(&p).unwrap()), + data_type: Box::new(FieldType::from_ident(&data_type).unwrap()), } }), "Vec" => get_sub_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()), + data_type: Box::new(FieldType::from_ident(&data_type).unwrap()), } }), - _struct_name => Some(FieldType::FieldTypeStruct { + _struct_name => { + Some(FieldType::FieldTypeStruct { struct_name: t.ident.clone(), - }), + })}, } } } pub fn get_field_type(field: &syn::Field) -> Option { match field.ty { - Path(ref path) => match path.path.segments.first() { - Some(Pair::End(t)) => FieldType::from_ident(t), - _ => None, + Path(ref path) => { + if path.path.segments.len() != 1 { + return None; + } + match path.path.segments.first() { + Some(Pair::End(t)) => FieldType::from_ident(t), + _ => { + None + }, + } }, _ => None, } } -fn get_sub_type(t: &syn::PathSegment) -> Option { +fn get_sub_type(t: &syn::PathSegment) -> Option { if let syn::PathArguments::AngleBracketed(ref args) = t.arguments { if let Some(Pair::End(tt)) = args.args.first() { if let syn::GenericArgument::Type(ref argument) = *tt { if let Path(ref path2) = *argument { if let Some(Pair::End(ttt)) = path2.path.segments.first() { - return Some(ttt.ident.clone()); + return Some(ttt.clone()); } } } diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index eaad87b..fe6e757 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -23,14 +23,14 @@ pub fn serialize( } let renamed_label = match field_attrs.rename { - Some(value) => Some(Ident::new(&format!("{}", value), Span::call_site())), - None => field.ident.clone(), + Some(value) => Ident::new(&format!("{}", value), Span::call_site()), + None => field.ident.clone().unwrap(), }; let label = &field.ident; let label_name = if let Some(prefix) = field_attrs.prefix { - prefix + ":" + renamed_label.unwrap().to_string().as_ref() + prefix + ":" + renamed_label.to_string().as_ref() } else { - renamed_label.unwrap().to_string() + renamed_label.to_string() }; match get_field_type(field) { @@ -93,6 +93,20 @@ pub fn serialize( struct_start_event }; }), + Some(&FieldType::FieldTypeVec{..}) => { + 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 end_event = XmlEvent::end_element(); + let _ret = writer.write(end_event); + } + }) + } _ => None, } } @@ -153,14 +167,14 @@ pub fn serialize( } let renamed_label = match field_attrs.rename { - Some(value) => Some(Ident::new(&format!("{}", value), Span::call_site())), - None => field.ident.clone(), + Some(value) => Ident::new(&format!("{}", value), Span::call_site()), + None => field.ident.clone().unwrap(), }; let label_name = if let Some(prefix) = field_attrs.prefix { - prefix + ":" + renamed_label.unwrap().to_string().as_ref() + prefix + ":" + renamed_label.to_string().as_ref() } else { - renamed_label.unwrap().to_string() + renamed_label.to_string() }; match get_field_type(field) { @@ -233,18 +247,35 @@ pub fn serialize( let _ret = writer.write(end_event); } }), + Some(&FieldType::FieldTypeVec{ .. }) => Some(quote!{ + if let Some(ref items) = &self.#label { + for item in items.iter() { + let start_event = XmlEvent::start_element(#label_name); + let _ret = writer.write(start_event); + + let value = format!("{}", item); + let data_event = XmlEvent::characters(&value); + let _ret = writer.write(data_event); + + let end_event = XmlEvent::end_element(); + let _ret = writer.write(end_event); + } + } + }), _ => None, } } - Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{ - writer.set_skip_start_end(false); - match self.#label.serialize(writer) { - Ok(()) => {}, - Err(msg) => { - return Err(msg); - }, - }; - }), + Some(FieldType::FieldTypeStruct { .. }) => { + Some(quote!{ + writer.set_skip_start_end(false); + match self.#label.serialize(writer) { + Ok(()) => {}, + Err(msg) => { + return Err(msg); + }, + }; + }) + }, Some(FieldType::FieldTypeVec { data_type }) => { let dt = Box::into_raw(data_type); match unsafe { dt.as_ref() } { @@ -313,7 +344,7 @@ pub fn serialize( unimplemented!(); } } - } + }, None => None, } })