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![