1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#![deny(missing_docs)] //! The maybe_macro crate exports one macro, the `maybe!` macro. //! //! The `maybe!` macro makes it neat to construct an option from a value in //! one line of code if it meets a certain condition. See the macro itself for //! more documentation about how to use it. /// The maybe macro. /// /// This macro takes a name and then an `if` or `if let` statement. If the /// conditional is true or the pattern matches, the macro evaluates to `Some`. /// Otherwise, it evaluates to `None`. /// /// What the macro will evaluate - that comes before the `if` statement - must /// be an identifier, it can't be any expression. /// /// # Using with `if` /// /// ``` /// // This will filter out every value greater than 10. /// slice.iter().filter_map(|&x| maybe!(x if < 10)) /// ``` /// /// # Using with `if let` /// /// ``` /// // This will filter out all error values. /// slice.iter().filter_map(|x| maybe!(x if let Ok(_) = x)); /// ``` /// /// Note that ident you return can also come from destructuring in the /// pattern: /// /// ``` /// slice.iter().filter_map(|x| maybe!(inner if let Ok(inner) = x)); /// ``` #[macro_export] macro_rules! maybe { ($i:ident if $e:expr) => { if $e { Some($i) } else { None } }; ($i:ident if let $p:pat = $e:expr) => { if let $p = $e { Some($i) } else { None } }; } #[cfg(test)] mod tests { #[test] fn conditional() { let x = 0; let x = maybe!(x if x > 0); assert_eq!(x, None); let x = 1; let x = maybe!(x if x > 0); assert_eq!(x, Some(1)); } #[test] fn pattern() { let x = 0; let x = maybe!(x if let 1...10 = x); assert_eq!(x, None); let x = 1; let x = maybe!(x if let 1...10 = x); assert_eq!(x, Some(1)); } #[test] fn destructure() { let x: Result<i32, ()> = Ok(0); let x = maybe!(i if let Ok(i) = x); assert_eq!(x, Some(0)); } }