diff --git a/src/macros.rs b/src/macros.rs index 5516bdb1..97a51960 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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 diff --git a/tests/macros.rs b/tests/macros.rs old mode 100644 new mode 100755 index 24744223..38f32597 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -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::().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::().is_ok()); + assert!("Bravo".parse::().is_ok()); + }) + }; + } + macro_rules! test_greek_meta { + {$arg_enum:item} => { + test_greek!($arg_enum, { + // FromStr implementation + assert_eq!("Alpha".parse::(), Ok(Greek::Alpha)); + assert_eq!("Bravo".parse::(), Ok(Greek::Bravo)); + }) + }; } - assert_eq!("Alpha".parse::(), 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::(), 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, + } + } + }; }