Skip to content

Commit

Permalink
fix(arg_enum!): Invalid expansions of some trailing-comma patterns
Browse files Browse the repository at this point in the history
In particular, fix macros that take an enum of one of the the following forms:

 - `#[...] enum { ... , }`
 - `pub enum { ... , }`
 - `enum { ... , }`

Previously, these expansions would result in an error message like "error: no
rules expected the token `:`".

Add extensive tests for each pattern.  Only two of the patterns had tests
before, so these errors did not surface automatically.
  • Loading branch information
brkalmar committed Apr 7, 2018
1 parent c8fed27 commit 7023184
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 27 deletions.
25 changes: 15 additions & 10 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,11 @@ macro_rules! arg_enum {
);
};
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
arg_enum!($(#[$($m:meta),+])+
enum $e:ident {
$($v:ident $(=$val:expr)*),+
}
arg_enum!(@impls
($(#[$($m),+])+
enum $e {
$($v$(=$val)*),+
}) -> ($e, $($v),+)
);
};
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
Expand All @@ -377,9 +378,11 @@ macro_rules! arg_enum {
);
};
(pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
arg_enum!(pub enum $e:ident {
$($v:ident $(=$val:expr)*),+
});
arg_enum!(@impls
(pub enum $e {
$($v$(=$val)*),+
}) -> ($e, $($v),+)
);
};
(pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
arg_enum!(@impls
Expand All @@ -389,9 +392,11 @@ macro_rules! arg_enum {
);
};
(enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
arg_enum!(enum $e:ident {
$($v:ident $(=$val:expr)*),+
});
arg_enum!(@impls
(enum $e {
$($v$(=$val)*),+
}) -> ($e, $($v),+)
);
};
(enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
arg_enum!(@impls
Expand Down
125 changes: 108 additions & 17 deletions tests/macros.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -251,24 +251,115 @@ fn group_macro_set_not_required() {

#[test]
fn arg_enum() {
arg_enum!{
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Greek {
Alpha,
Bravo
}
// Helper macros to avoid repetition
macro_rules! test_greek {
($arg_enum:item, $tests:block) => {{
$arg_enum
// FromStr implementation
assert!("Charlie".parse::<Greek>().is_err());
// Display implementation
assert_eq!(format!("{}", Greek::Alpha), "Alpha");
assert_eq!(format!("{}", Greek::Bravo), "Bravo");
// fn variants()
assert_eq!(Greek::variants(), ["Alpha", "Bravo"]);
// rest of tests
$tests
}};
}
macro_rules! test_greek_no_meta {
{$arg_enum:item} => {
test_greek!($arg_enum, {
// FromStr implementation
assert!("Alpha".parse::<Greek>().is_ok());
assert!("Bravo".parse::<Greek>().is_ok());
})
};
}
macro_rules! test_greek_meta {
{$arg_enum:item} => {
test_greek!($arg_enum, {
// FromStr implementation
assert_eq!("Alpha".parse::<Greek>(), Ok(Greek::Alpha));
assert_eq!("Bravo".parse::<Greek>(), Ok(Greek::Bravo));
})
};
}
assert_eq!("Alpha".parse::<Greek>(), Ok(Greek::Alpha));
}

#[test]
fn arg_enum_trailing_comma() {
arg_enum!{
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Greek {
Alpha,
Bravo,
// Tests for each pattern
// meta NO, pub NO, trailing comma NO
test_greek_no_meta!{
arg_enum!{
enum Greek {
Alpha,
Bravo
}
}
}
assert_eq!("Alpha".parse::<Greek>(), Ok(Greek::Alpha));
};
// meta NO, pub NO, trailing comma YES
test_greek_no_meta!{
arg_enum!{
enum Greek {
Alpha,
Bravo,
}
}
};
// meta NO, pub YES, trailing comma NO
test_greek_no_meta!{
arg_enum!{
pub enum Greek {
Alpha,
Bravo
}
}
};
// meta NO, pub YES, trailing comma YES
test_greek_no_meta!{
arg_enum!{
pub enum Greek {
Alpha,
Bravo,
}
}
};
// meta YES, pub NO, trailing comma NO
test_greek_meta!{
arg_enum!{
#[derive(Debug, PartialEq, Copy, Clone)]
enum Greek {
Alpha,
Bravo
}
}
};
// meta YES, pub NO, trailing comma YES
test_greek_meta!{
arg_enum!{
#[derive(Debug, PartialEq, Copy, Clone)]
enum Greek {
Alpha,
Bravo,
}
}
};
// meta YES, pub YES, trailing comma NO
test_greek_meta!{
arg_enum!{
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Greek {
Alpha,
Bravo
}
}
};
// meta YES, pub YES, trailing comma YES
test_greek_meta!{
arg_enum!{
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Greek {
Alpha,
Bravo,
}
}
};
}

0 comments on commit 7023184

Please sign in to comment.