mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +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)*,)+ } ) => {
|
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||||
$crate::arg_enum!($(#[$($m:meta),+])+
|
$crate::arg_enum!(@impls
|
||||||
enum $e:ident {
|
($(#[$($m),+])+
|
||||||
$($v:ident $(=$val:expr)*),+
|
enum $e {
|
||||||
}
|
$($v$(=$val)*),+
|
||||||
|
}) -> ($e, $($v),+)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
($(#[$($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)*,)+ } ) => {
|
(pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||||
$crate::arg_enum!(pub enum $e:ident {
|
$crate::arg_enum!(@impls
|
||||||
$($v:ident $(=$val:expr)*),+
|
(pub enum $e {
|
||||||
});
|
$($v$(=$val)*),+
|
||||||
|
}) -> ($e, $($v),+)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
(pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
(pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||||
$crate::arg_enum!(@impls
|
$crate::arg_enum!(@impls
|
||||||
|
@ -398,9 +401,11 @@ macro_rules! arg_enum {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
(enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
(enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||||
$crate::arg_enum!(enum $e:ident {
|
$crate::arg_enum!(@impls
|
||||||
$($v:ident $(=$val:expr)*),+
|
(enum $e {
|
||||||
});
|
$($v$(=$val)*),+
|
||||||
|
}) -> ($e, $($v),+)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
(enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
(enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||||
$crate::arg_enum!(@impls
|
$crate::arg_enum!(@impls
|
||||||
|
|
103
tests/macros.rs
Normal file → Executable file
103
tests/macros.rs
Normal file → Executable file
|
@ -286,6 +286,99 @@ fn group_macro_set_not_required() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn arg_enum() {
|
fn arg_enum() {
|
||||||
|
// 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));
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests for each pattern
|
||||||
|
// meta NO, pub NO, trailing comma NO
|
||||||
|
test_greek_no_meta! {
|
||||||
|
arg_enum!{
|
||||||
|
enum Greek {
|
||||||
|
Alpha,
|
||||||
|
Bravo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 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!{
|
arg_enum!{
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
pub enum Greek {
|
pub enum Greek {
|
||||||
|
@ -293,11 +386,9 @@ fn arg_enum() {
|
||||||
Bravo
|
Bravo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert_eq!("Alpha".parse::<Greek>(), Ok(Greek::Alpha));
|
};
|
||||||
}
|
// meta YES, pub YES, trailing comma YES
|
||||||
|
test_greek_meta! {
|
||||||
#[test]
|
|
||||||
fn arg_enum_trailing_comma() {
|
|
||||||
arg_enum!{
|
arg_enum!{
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
pub enum Greek {
|
pub enum Greek {
|
||||||
|
@ -305,5 +396,5 @@ fn arg_enum_trailing_comma() {
|
||||||
Bravo,
|
Bravo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert_eq!("Alpha".parse::<Greek>(), Ok(Greek::Alpha));
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue