diff --git a/yaserde/tests/serializer.rs b/yaserde/tests/serializer.rs
index e1f9090..39dbe07 100644
--- a/yaserde/tests/serializer.rs
+++ b/yaserde/tests/serializer.rs
@@ -200,3 +200,68 @@ fn ser_text_content_with_attributes() {
let content = "text_content";
convert_and_validate!(model, content);
}
+
+#[test]
+fn ser_enum() {
+ #[derive(YaSerialize, PartialEq, Debug)]
+ #[yaserde(root="base")]
+ pub struct XmlStruct {
+ color: Color
+ }
+
+ #[derive(YaSerialize, PartialEq, Debug)]
+ #[yaserde(root="color")]
+ pub enum Color {
+ White,
+ Black,
+ #[yaserde(rename="custom")]
+ Custom{
+ enabled: String,
+ color: RGBColor,
+ alpha: Alpha,
+ alphas: Vec,
+ }
+ }
+
+ impl Default for Color {
+ fn default() -> Color {
+ Color::White
+ }
+ }
+
+ #[derive(YaSerialize, PartialEq, Debug)]
+ pub struct RGBColor {
+ red: String,
+ green: String,
+ blue: String,
+ }
+
+ #[derive(YaSerialize, PartialEq, Debug)]
+ pub enum Alpha {
+ Transparent,
+ Opaque,
+ }
+
+ let model = XmlStruct{
+ color: Color::Black
+ };
+
+ let content = "Black";
+ convert_and_validate!(model, content);
+
+ let model = XmlStruct{
+ color: Color::Custom{
+ enabled: "true".to_string(),
+ color: RGBColor{
+ red: "0".to_string(),
+ green: "128".to_string(),
+ blue: "255".to_string(),
+ },
+ alpha: Alpha::Opaque,
+ alphas: vec![Alpha::Opaque, Alpha::Transparent]
+ }
+ };
+
+ let content = "true0128255OpaqueOpaqueTransparent";
+ convert_and_validate!(model, content);
+}
diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs
new file mode 100644
index 0000000..6985c14
--- /dev/null
+++ b/yaserde_derive/src/ser/expand_enum.rs
@@ -0,0 +1,150 @@
+
+use attribute::*;
+use field_type::*;
+use quote::Tokens;
+use syn::Fields;
+use syn::Ident;
+use syn::DataEnum;
+use proc_macro2::Span;
+
+pub fn serialize(data_enum: &DataEnum, name: &Ident, root: &String) -> Tokens {
+ let write_enum_content : Tokens = data_enum.variants.iter().map(|ref variant|
+ {
+ let field_attrs = YaSerdeAttribute::parse(&variant.attrs);
+ let renamed_label =
+ match field_attrs.rename {
+ Some(value) => Ident::new(&format!("{}", value), Span::call_site()),
+ None => variant.ident
+ };
+ let label = variant.ident;
+ let label_name = renamed_label.to_string();
+
+ match variant.fields {
+ Fields::Unit => {
+ Some(quote!{
+ name::#label => {
+ let data_event = XmlEvent::characters(#label_name);
+ let _ret = writer.write(data_event);
+ }
+ })
+ },
+ Fields::Named(ref fields) => {
+ let enum_fields = fields.named.iter().map(|ref field| {
+
+ let field_attrs = YaSerdeAttribute::parse(&field.attrs);
+ if field_attrs.attribute == true {
+ return None;
+ }
+
+ let field_label = field.ident;
+ if field_attrs.text == true {
+ return Some(quote!(
+ let data_event = XmlEvent::characters(&self.#field_label);
+ let _ret = writer.write(data_event);
+ ))
+ }
+
+ let renamed_field_label =
+ match field_attrs.rename {
+ Some(value) => Some(Ident::new(&format!("{}", value), Span::call_site())),
+ None => field.ident
+ };
+ let field_label_name = renamed_field_label.unwrap().to_string();
+
+
+ match get_field_type(field) {
+ Some(FieldType::FieldTypeString) =>
+ Some(quote!{
+ match self {
+ name::#label{ref #field_label, ..} => {
+ let struct_start_event = XmlEvent::start_element(#field_label_name);
+ let _ret = writer.write(struct_start_event);
+
+ let data_event = XmlEvent::characters(#field_label);
+ let _ret = writer.write(data_event);
+
+ let struct_end_event = XmlEvent::end_element();
+ let _ret = writer.write(struct_end_event);
+ },
+ _ => {},
+ }
+ }),
+ Some(FieldType::FieldTypeStruct{..}) =>
+ Some(quote!{
+ match self {
+ name::#label{ref #field_label, ..} => {
+ match #field_label.derive_serialize(writer) {
+ Ok(()) => {},
+ Err(msg) => {
+ return Err(msg);
+ },
+ };
+ },
+ _ => {}
+ }
+ }),
+ Some(FieldType::FieldTypeVec{..}) =>
+ Some(quote!{
+ match self {
+ name::#label{ref #field_label, ..} => {
+ for item in #field_label {
+ match item.derive_serialize(writer) {
+ Ok(()) => {},
+ Err(msg) => {
+ return Err(msg);
+ },
+ };
+ }
+ },
+ _ => {}
+ }
+ }),
+ _ => None
+ }
+ })
+ .filter(|x| x.is_some())
+ .map(|x| x.unwrap())
+ .fold(Tokens::new(), |mut tokens, token| {tokens.append_all(token); tokens});
+
+ Some(quote!{
+ name::#label{..} => {
+ let struct_start_event = XmlEvent::start_element(#label_name);
+ let _ret = writer.write(struct_start_event);
+
+ #enum_fields
+
+ let struct_end_event = XmlEvent::end_element();
+ let _ret = writer.write(struct_end_event);
+ }
+ })
+ },
+ Fields::Unnamed(ref _fields) => {
+ unimplemented!()
+ },
+ }
+ })
+ .filter(|x| x.is_some())
+ .map(|x| x.unwrap())
+ .fold(Tokens::new(), |mut tokens, token| {tokens.append_all(token); tokens});
+
+ // println!("{:?}", write_enum_content);
+
+ quote! {
+ use xml::writer::XmlEvent;
+
+ impl YaSerialize for #name {
+ #[allow(unused_variables)]
+ fn derive_serialize(&self, writer: &mut xml::EventWriter) -> Result<(), String> {
+ let struct_start_event = XmlEvent::start_element(#root);
+ let _ret = writer.write(struct_start_event);
+ match self {
+ #write_enum_content
+ }
+
+ let struct_end_event = XmlEvent::end_element();
+ let _ret = writer.write(struct_end_event);
+ Ok(())
+ }
+ }
+ }
+}
diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs
index c565613..8d4e9b8 100644
--- a/yaserde_derive/src/ser/mod.rs
+++ b/yaserde_derive/src/ser/mod.rs
@@ -1,4 +1,5 @@
+pub mod expand_enum;
pub mod expand_struct;
use attribute;
@@ -21,8 +22,8 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result {
expand_struct::serialize(data_struct, &name, &root)
},
- &syn::Data::Enum(ref _data_enum) => {
- unimplemented!()
+ &syn::Data::Enum(ref data_enum) => {
+ expand_enum::serialize(data_enum, &name, &root)
},
&syn::Data::Union(ref _data_union) => {
unimplemented!()