Implement syn::Variant
diff --git a/src/attr.rs b/src/attr.rs
index 83ad8d7..e865c1e 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -394,6 +394,7 @@
 pub mod parsing {
     use super::*;
     use buffer::Cursor;
+    use parse::{ParseStream, Result};
     use parse_error;
     use proc_macro2::{Literal, Punct, Spacing, Span, TokenTree};
     use synom::PResult;
@@ -405,6 +406,22 @@
     }
 
     impl Attribute {
+        pub fn parse_outer2(input: ParseStream) -> Result<Vec<Self>> {
+            let mut attrs = Vec::new();
+            while input.peek(Token![#]) {
+                attrs.push(input.parse_synom(Attribute::parse_outer)?);
+            }
+            Ok(attrs)
+        }
+
+        pub fn parse_inner2(input: ParseStream) -> Result<Vec<Self>> {
+            let mut attrs = Vec::new();
+            while input.peek(Token![#]) {
+                attrs.push(input.parse_synom(Attribute::parse_inner)?);
+            }
+            Ok(attrs)
+        }
+
         named!(pub parse_inner -> Self, alt!(
             do_parse!(
                 pound: punct!(#) >>
diff --git a/src/data.rs b/src/data.rs
index 53858ae..41af7a8 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -189,28 +189,28 @@
     use synom::ext::IdentExt;
     use synom::Synom;
 
-    impl Synom for Variant {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            id: syn!(Ident) >>
-            fields: alt!(
-                syn!(FieldsNamed) => { Fields::Named }
-                |
-                syn!(FieldsUnnamed) => { Fields::Unnamed }
-                |
-                epsilon!() => { |_| Fields::Unit }
-            ) >>
-            disr: option!(tuple!(punct!(=), syn!(Expr))) >>
-            (Variant {
-                ident: id,
-                attrs: attrs,
-                fields: fields,
-                discriminant: disr,
+    impl Parse for Variant {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(Variant {
+                attrs: input.call(Attribute::parse_outer2)?,
+                ident: input.parse()?,
+                fields: {
+                    if input.peek(token::Brace) {
+                        Fields::Named(input.parse_synom(FieldsNamed::parse)?)
+                    } else if input.peek(token::Paren) {
+                        Fields::Unnamed(input.parse_synom(FieldsUnnamed::parse)?)
+                    } else {
+                        Fields::Unit
+                    }
+                },
+                discriminant: {
+                    if input.peek(Token![=]) {
+                        Some((input.parse()?, input.parse_synom(Expr::parse)?))
+                    } else {
+                        None
+                    }
+                },
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("enum variant")
         }
     }
 
diff --git a/src/parse.rs b/src/parse.rs
index 2525d8f..cfc0817 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -115,6 +115,10 @@
         T::parse(self)
     }
 
+    pub fn call<T>(&self, function: fn(ParseStream) -> Result<T>) -> Result<T> {
+        function(self)
+    }
+
     pub fn peek<T: Peek>(&self, token: T) -> bool {
         self.lookahead1().peek(token)
     }