diff --git a/yaserde/tests/deserializer.rs b/yaserde/tests/deserializer.rs index 2009a5b..42f2fd5 100644 --- a/yaserde/tests/deserializer.rs +++ b/yaserde/tests/deserializer.rs @@ -440,6 +440,26 @@ fn de_text_content_with_attributes() { ); } +#[test] +fn de_text_attribute_on_optional_string() { + #[derive(YaDeserialize, PartialEq, Debug)] + #[yaserde(rename = "base")] + pub struct XmlStruct { + #[yaserde(text)] + text: Option, + } + + let model = XmlStruct { + text: Some("Testing text".to_string()), + }; + let content = r#"Testing text"#; + convert_and_validate!(content, XmlStruct, model); + + let model = XmlStruct { text: None }; + let content = r#""#; + convert_and_validate!(content, XmlStruct, model); +} + #[test] fn de_enum() { init(); diff --git a/yaserde/tests/flatten.rs b/yaserde/tests/flatten.rs index bc669b0..4a8b4f0 100644 --- a/yaserde/tests/flatten.rs +++ b/yaserde/tests/flatten.rs @@ -54,7 +54,7 @@ fn basic_flatten() { fn default() -> Self { DateKind::Working } - }; + } let model = DateTime { date: Date { diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs index 8abe69b..12dfdd3 100644 --- a/yaserde/tests/serializer.rs +++ b/yaserde/tests/serializer.rs @@ -324,6 +324,28 @@ fn ser_text_content_with_attributes() { serialize_and_validate!(model, content); } +#[test] +fn ser_text_attribute_on_optional_string() { + #[derive(YaSerialize, PartialEq, Debug)] + #[yaserde(rename = "base")] + pub struct XmlStruct { + #[yaserde(text)] + text: Option, + } + + let model = XmlStruct { + text: Some("Testing text".to_string()), + }; + + let content = r#"Testing text"#; + serialize_and_validate!(model, content); + + let model = XmlStruct { text: None }; + + let content = r#""#; + serialize_and_validate!(model, content); +} + #[test] fn ser_keyword() { #[derive(YaSerialize, PartialEq, Debug)] diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 4c83918..9fbc67c 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -303,7 +303,13 @@ pub fn parse( match field.get_type() { Field::FieldString => set_text("e! { text_content.to_owned() }), - Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None, + Field::FieldOption { data_type } => match *data_type { + Field::FieldString => set_text( + "e! { if text_content.is_empty() { None } else { Some(text_content.to_owned()) }}, + ), + _ => None, + }, + Field::FieldStruct { .. } | Field::FieldVec { .. } => None, simple_type => { let type_token: TokenStream = simple_type.into(); set_text("e! { #type_token::from_str(text_content).unwrap() }) diff --git a/yaserde_derive/src/lib.rs b/yaserde_derive/src/lib.rs index f09ab20..9d881a1 100644 --- a/yaserde_derive/src/lib.rs +++ b/yaserde_derive/src/lib.rs @@ -14,7 +14,7 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); match de::expand_derive_deserialize(&ast) { Ok(expanded) => expanded.into(), - Err(msg) => panic!(msg), + Err(msg) => panic!("{}", msg), } } @@ -23,6 +23,6 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); match ser::expand_derive_serialize(&ast) { Ok(expanded) => expanded.into(), - Err(msg) => panic!(msg), + Err(msg) => panic!("{}", msg), } } diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index b90ce20..3ec41bf 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -145,10 +145,17 @@ pub fn serialize( .map(|field| { let label = field.label(); if field.is_text_content() { - return Some(quote!( - let data_event = ::xml::writer::XmlEvent::characters(&self.#label); - writer.write(data_event).map_err(|e| e.to_string())?; - )); + return match field.get_type() { + Field::FieldOption { .. } => Some(quote!( + let s = self.#label.as_deref().unwrap_or_default(); + let data_event = ::xml::writer::XmlEvent::characters(s); + writer.write(data_event).map_err(|e| e.to_string())?; + )), + _ => Some(quote!( + let data_event = ::xml::writer::XmlEvent::characters(&self.#label); + writer.write(data_event).map_err(|e| e.to_string())?; + )), + }; } let label_name = field.renamed_label(root_attributes);