mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 14:22:34 +00:00
fix(arg_enum!): Invalid expansions of some trailing-comma patterns
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.
This commit is contained in:
parent
0f3bdc439e
commit
4bf3f97d28
2 changed files with 123 additions and 27 deletions
|
@ -371,10 +371,11 @@ macro_rules! arg_enum {
|
|||
);
|
||||
};
|
||||
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!($(#[$($m:meta),+])+
|
||||
enum $e:ident {
|
||||
$($v:ident $(=$val:expr)*),+
|
||||
}
|
||||
$crate::arg_enum!(@impls
|
||||
($(#[$($m),+])+
|
||||
enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
|
@ -386,9 +387,11 @@ macro_rules! arg_enum {
|
|||
);
|
||||
};
|
||||
(pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!(pub enum $e:ident {
|
||||
$($v:ident $(=$val:expr)*),+
|
||||
});
|
||||
$crate::arg_enum!(@impls
|
||||
(pub enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
(pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
|
@ -398,9 +401,11 @@ macro_rules! arg_enum {
|
|||
);
|
||||
};
|
||||
(enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!(enum $e:ident {
|
||||
$($v:ident $(=$val:expr)*),+
|
||||
});
|
||||
$crate::arg_enum!(@impls
|
||||
(enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
(enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
|
|
125
tests/macros.rs
Normal file → Executable file
125
tests/macros.rs
Normal file → Executable file
|
@ -286,24 +286,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,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue