Terminated list helper
diff --git a/src/attr.rs b/src/attr.rs
index cb0eeec..46a3339 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -184,7 +184,7 @@
         do_parse!(
             id: ident >>
             punct!("(") >>
-            inner: separated_list!(punct!(","), meta_item) >>
+            inner: terminated_list!(punct!(","), meta_item) >>
             punct!(")") >>
             (MetaItem::List(id, inner))
         )
diff --git a/src/constant.rs b/src/constant.rs
index 2834539..1ebac7f 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -55,7 +55,7 @@
 
     named!(and_call -> Vec<ConstExpr>, do_parse!(
         punct!("(") >>
-        args: separated_list!(punct!(","), const_expr) >>
+        args: terminated_list!(punct!(","), const_expr) >>
         punct!(")") >>
         (args)
     ));
diff --git a/src/data.rs b/src/data.rs
index 71d6754..9e8e9b4 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -66,8 +66,7 @@
 
     named!(pub enum_body -> Vec<Variant>, do_parse!(
         punct!("{") >>
-        variants: separated_list!(punct!(","), variant) >>
-        option!(punct!(",")) >>
+        variants: terminated_list!(punct!(","), variant) >>
         punct!("}") >>
         (variants)
     ));
@@ -93,16 +92,14 @@
 
     named!(pub struct_like_body -> Vec<Field>, do_parse!(
         punct!("{") >>
-        fields: separated_list!(punct!(","), struct_field) >>
-        option!(punct!(",")) >>
+        fields: terminated_list!(punct!(","), struct_field) >>
         punct!("}") >>
         (fields)
     ));
 
     named!(tuple_like_body -> Vec<Field>, do_parse!(
         punct!("(") >>
-        fields: separated_list!(punct!(","), tuple_field) >>
-        option!(punct!(",")) >>
+        fields: terminated_list!(punct!(","), tuple_field) >>
         punct!(")") >>
         (fields)
     ));
diff --git a/src/expr.rs b/src/expr.rs
index d370f34..4f5c73f 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -422,16 +422,14 @@
 
     named!(expr_vec -> Expr, do_parse!(
         punct!("[") >>
-        elems: separated_list!(punct!(","), expr) >>
-        cond!(!elems.is_empty(), option!(punct!(","))) >>
+        elems: terminated_list!(punct!(","), expr) >>
         punct!("]") >>
         (Expr::Vec(elems))
     ));
 
     named!(and_call -> Vec<Expr>, do_parse!(
         punct!("(") >>
-        args: separated_list!(punct!(","), expr) >>
-        cond!(!args.is_empty(), option!(punct!(","))) >>
+        args: terminated_list!(punct!(","), expr) >>
         punct!(")") >>
         (args)
     ));
@@ -443,21 +441,19 @@
             punct!("::"),
             delimited!(
                 punct!("<"),
-                separated_list!(punct!(","), ty),
+                terminated_list!(punct!(","), ty),
                 punct!(">")
             )
         )) >>
         punct!("(") >>
-        args: separated_list!(punct!(","), expr) >>
-        cond!(!args.is_empty(), option!(punct!(","))) >>
+        args: terminated_list!(punct!(","), expr) >>
         punct!(")") >>
         (method, ascript, args)
     ));
 
     named!(expr_tup -> Expr, do_parse!(
         punct!("(") >>
-        elems: separated_list!(punct!(","), expr) >>
-        cond!(!elems.is_empty(), option!(punct!(","))) >>
+        elems: terminated_list!(punct!(","), expr) >>
         punct!(")") >>
         (Expr::Tup(elems))
     ));
@@ -583,8 +579,7 @@
     named!(expr_closure -> Expr, do_parse!(
         capture: capture_by >>
         punct!("|") >>
-        inputs: separated_list!(punct!(","), closure_arg) >>
-        cond!(!inputs.is_empty(), option!(punct!(","))) >>
+        inputs: terminated_list!(punct!(","), closure_arg) >>
         punct!("|") >>
         ret_and_body: alt!(
             do_parse!(
@@ -898,6 +893,7 @@
             cond!(!fields.is_empty(), punct!(",")),
             punct!("..")
         )) >>
+        cond!(!fields.is_empty() && more.is_none(), option!(punct!(","))) >>
         punct!("}") >>
         (Pat::Struct(path, fields, more.is_some()))
     ));
diff --git a/src/generics.rs b/src/generics.rs
index dc3dd0d..3d7bd86 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -227,7 +227,7 @@
     named!(pub bound_lifetimes -> Vec<LifetimeDef>, opt_vec!(do_parse!(
         keyword!("for") >>
         punct!("<") >>
-        lifetimes: separated_list!(punct!(","), lifetime_def) >>
+        lifetimes: terminated_list!(punct!(","), lifetime_def) >>
         punct!(">") >>
         (lifetimes)
     )));
diff --git a/src/helper.rs b/src/helper.rs
index cc08c9a..734299d 100644
--- a/src/helper.rs
+++ b/src/helper.rs
@@ -84,11 +84,22 @@
 
 macro_rules! separated_list {
     ($i:expr, punct!($sep:expr), $f:expr) => {
-        $crate::helper::separated_list($i, $sep, $f)
+        $crate::helper::separated_list($i, $sep, $f, false)
     };
 }
 
-pub fn separated_list<'a, T>(mut input: &'a str, sep: &'static str, f: fn(&'a str) -> IResult<&'a str, T>) -> IResult<&'a str, Vec<T>> {
+macro_rules! terminated_list {
+    ($i:expr, punct!($sep:expr), $f:expr) => {
+        $crate::helper::separated_list($i, $sep, $f, true)
+    };
+}
+
+pub fn separated_list<'a, T>(
+    mut input: &'a str,
+    sep: &'static str,
+    f: fn(&'a str) -> IResult<&'a str, T>,
+    terminated: bool,
+) -> IResult<&'a str, Vec<T>> {
     let mut res = Vec::new();
 
     // get the first element
@@ -118,6 +129,11 @@
                         break;
                     }
                 }
+                if terminated {
+                    if let IResult::Done(after, _) = punct(input, sep) {
+                        input = after;
+                    }
+                }
                 IResult::Done(input, res)
             }
         }
diff --git a/src/item.rs b/src/item.rs
index 254a6b1..b6da994 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -426,8 +426,7 @@
         name: ident >>
         generics: generics >>
         punct!("(") >>
-        inputs: separated_list!(punct!(","), fn_arg) >>
-        cond!(!inputs.is_empty(), option!(punct!(","))) >>
+        inputs: terminated_list!(punct!(","), fn_arg) >>
         punct!(")") >>
         ret: option!(preceded!(punct!("->"), ty)) >>
         where_clause: where_clause >>
@@ -525,8 +524,7 @@
         name: ident >>
         generics: generics >>
         punct!("(") >>
-        inputs: separated_list!(punct!(","), fn_arg) >>
-        cond!(!inputs.is_empty(), option!(punct!(","))) >>
+        inputs: terminated_list!(punct!(","), fn_arg) >>
         punct!(")") >>
         ret: option!(preceded!(punct!("->"), ty)) >>
         where_clause: where_clause >>
@@ -703,8 +701,7 @@
         name: ident >>
         generics: generics >>
         punct!("(") >>
-        inputs: separated_list!(punct!(","), fn_arg) >>
-        cond!(!inputs.is_empty(), option!(punct!(","))) >>
+        inputs: terminated_list!(punct!(","), fn_arg) >>
         punct!(")") >>
         ret: option!(preceded!(punct!("->"), ty)) >>
         where_clause: where_clause >>
@@ -847,8 +844,7 @@
         name: ident >>
         generics: generics >>
         punct!("(") >>
-        inputs: separated_list!(punct!(","), fn_arg) >>
-        cond!(!inputs.is_empty(), option!(punct!(","))) >>
+        inputs: terminated_list!(punct!(","), fn_arg) >>
         punct!(")") >>
         ret: option!(preceded!(punct!("->"), ty)) >>
         where_clause: where_clause >>
diff --git a/src/ty.rs b/src/ty.rs
index 011f0f9..5c8af13 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -270,11 +270,11 @@
         keyword!("fn") >>
         lifetimes: opt_vec!(delimited!(
             punct!("<"),
-            separated_list!(punct!(","), lifetime_def),
+            terminated_list!(punct!(","), lifetime_def),
             punct!(">")
         )) >>
         punct!("(") >>
-        inputs: separated_list!(punct!(","), fn_arg) >>
+        inputs: terminated_list!(punct!(","), fn_arg) >>
         punct!(")") >>
         output: option!(preceded!(
             punct!("->"),
@@ -294,7 +294,7 @@
 
     named!(ty_tup -> Ty, do_parse!(
         punct!("(") >>
-        elems: separated_list!(punct!(","), ty) >>
+        elems: terminated_list!(punct!(","), ty) >>
         punct!(")") >>
         (Ty::Tup(elems))
     ));
@@ -322,8 +322,7 @@
 
     named!(parenthesized_parameter_data -> PathParameters, do_parse!(
         punct!("(") >>
-        inputs: separated_list!(punct!(","), ty) >>
-        cond!(!inputs.is_empty(), option!(punct!(","))) >>
+        inputs: terminated_list!(punct!(","), ty) >>
         punct!(")") >>
         output: option!(preceded!(
             punct!("->"),
@@ -371,7 +370,7 @@
     named!(ty_poly_trait_ref -> Ty, do_parse!(
         keyword!("for") >>
         punct!("<") >>
-        lifetimes: separated_list!(punct!(","), lifetime_def) >>
+        lifetimes: terminated_list!(punct!(","), lifetime_def) >>
         punct!(">") >>
         trait_ref: path >>
         (Ty::PolyTraitRef(vec![