├── .gitignore ├── Cargo.toml ├── README.md ├── examples └── simple.rs └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "fallthrough" 4 | version = "0.0.1" 5 | authors = ["Joshua Yanovski "] 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fallthrough 2 | 3 | A macro providing fallthrough `match`. 4 | 5 | ## Requirements 6 | 7 | Include the following in your `Cargo.toml`: 8 | 9 | ```toml 10 | [dependencies.fallthrough] 11 | git = "https://github.com/pythonesque/fallthrough" 12 | version = "0.0.1" 13 | ``` 14 | 15 | In your `lib.rs`: 16 | 17 | ```rust 18 | #[macro_use] extern crate fallthrough; 19 | ``` 20 | 21 | ## Usage 22 | 23 | ```rust 24 | #[allow(unreachable_code)] 25 | fn main() { 26 | let mut x = 0; 27 | 28 | match_fallthrough!(x, { 29 | 0 => { assert_eq!(x,0); x = 1; }, 30 | 1 => { assert_eq!(x,1); x = 2; break; }, 31 | _ => { panic!("Should not reach the default case"); }, 32 | }); 33 | assert_eq!(x, 2); 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /examples/simple.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate fallthrough; 2 | 3 | #[allow(unreachable_code)] 4 | fn main() { 5 | let mut x = 0; 6 | 7 | match_fallthrough!(x, { 8 | 0 => { assert_eq!(x,0); x = 1; }, 9 | 1 => { assert_eq!(x,1); x = 2; break; }, 10 | _ => { panic!("Should not reach the default case"); }, 11 | }); 12 | assert_eq!(x, 2); 13 | } 14 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_export] 2 | macro_rules! match_fallthrough_make_match { 3 | ($elem:expr, ($($pat:pat => $branch:expr)*)) => {{ 4 | match $elem {$( 5 | $pat => $branch, 6 | )*} 7 | }} 8 | } 9 | 10 | #[macro_export] 11 | macro_rules! match_fallthrough_make_loops { 12 | ($test:expr, $exit:expr, ($pat:pat => $branch:expr); ($($p:pat => $r:expr)*)) => {{ 13 | 'fallthrough: loop { 14 | loop { 15 | match_fallthrough_make_match!($test, ($pat => break 'fallthrough $($p => $r)*)); 16 | } 17 | $exit 18 | } 19 | $branch 20 | }}; 21 | ($test:expr, $exit:expr, ($pat:pat => $branch:expr, $($pu:pat => $bu:expr),+) ; ($($p:pat => $r:expr)*)) => {{ 22 | 'fallthrough: loop { 23 | loop { 24 | match_fallthrough_make_loops!($test, $exit, ($($pu => $bu),+) ; ($pat => break 'fallthrough $($p => $r)*)); 25 | break 'fallthrough 26 | } 27 | $exit 28 | } 29 | $branch 30 | }}; 31 | } 32 | 33 | #[macro_export] 34 | macro_rules! match_fallthrough_reverse_branches { 35 | ($test:expr, ($pat:pat => $branch:expr); ($($p:pat => $r:expr)*)) => {{ 36 | 'exit: loop { 37 | match_fallthrough_make_loops!($test, break 'exit, ($pat => $branch, $($p => $r),*); ()); 38 | break; 39 | } 40 | }}; 41 | ($test:expr, ($pat:pat => $branch:expr, $($pu:pat => $bu:expr),+); ($($p:pat => $r:expr)*)) => (( 42 | match_fallthrough_reverse_branches!($test, ( $($pu => $bu),+ ) ; ($pat => $branch $($p => $r)*)) 43 | )) 44 | } 45 | 46 | #[macro_export] 47 | macro_rules! match_fallthrough { 48 | ($test:expr, { $( $pat:pat => $branch:expr ),+ } ) => {{ 49 | match_fallthrough_reverse_branches!($test, ($($pat => $branch),+); ()) 50 | }}; 51 | ($test:expr, { $( $pat:pat => $branch:expr, )+ } ) => {{ 52 | match_fallthrough_reverse_branches!($test, ($($pat => $branch),+); ()) 53 | }} 54 | } 55 | 56 | #[test] 57 | #[allow(unreachable_code)] 58 | fn it_works() { 59 | let mut x = 0; 60 | 61 | match_fallthrough!(x, { 62 | 0 => { assert_eq!(x,0); x = 1; }, 63 | 1 => { assert_eq!(x,1); x = 2; break; }, 64 | _ => { panic!("Should not reach the default case"); }, 65 | }); 66 | assert_eq!(x, 2); 67 | } 68 | --------------------------------------------------------------------------------