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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
/* Copyright (c) 2018 Garrett Berg, vitiral@gmail.com * * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or * http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or * http://opensource.org/licenses/MIT>, at your option. This file may not be * copied, modified, or distributed except according to those terms. */ //! **The `expect!` macro** //! //! This crate adds the `expect!` macro, which is basically just calling //! `.expect` on your type but also: //! //! - Includes the exact line number of the error //! - Allows you to specify a custom error message with formatting. //! //! This gives you panic messages like this: //! //! ```no_compile //! thread 'example' panicked at '"expect error"', src/lib.rs:5:5 //! ``` //! //! As opposed to: //! //! ```no_compile //! thread 'example' panicked at 'called `Result::unwrap()` on an `Err` value: "expect error"', libcore/result.rs:945:5 //! ``` /// Unwrap a result or `panic!` with a message. /// /// Works with [`Result`], [`Option`] and anything else with the `unwrap_or_else` method. /// /// This macro has two forms: /// /// - `expect!(result)`: calls `panic!("{:#?}", err)` on any unwrapped `Err`/`None`. /// - `expect!(result, ...)`: calls `panic!(...)` on any unwrapped `Err`/`None`, allowing you to /// specify your own error formatting. This is recommened when you are using `expect!` with /// [`Option`] /// /// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html /// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html /// /// # Example /// /// Without format /// /// ```rust,should_panic /// #[macro_use] extern crate expect_macro; /// /// # fn main() { /// let result = Err("expect error"); /// expect!(result); /// # } /// /// // COMPILER OUTPUT: /// // thread 'example' panicked at '"expect error"', src/lib.rs:5:5 /// ``` /// /// With format /// /// ```rust,should_panic /// #[macro_use] extern crate expect_macro; /// /// # fn main() { /// let result = Err("expect error"); /// expect!(result, "Some values: {}, {}", 1, 2); /// # } /// /// // COMPILER OUTPUT: /// // thread 'example' panicked at 'Some values: 1, 2', src/lib.rs:5:5 /// ``` /// /// #[macro_export] macro_rules! expect { [$result:expr, $($rest:tt)*] => { $result.unwrap_or_else(|_| { panic!($($rest)*) }) }; [$result:expr] => { $result.unwrap_or_else(|e| { panic!("{:?}", e) }) }; } #[test] #[should_panic] fn expect_panic_bare() { expect!(Err("expect error")); } #[test] #[should_panic] fn regular_panic_bare() { let result: Result<(), &str> = Err("expect error"); result.unwrap(); } #[test] #[should_panic] fn expect_panic_msg() { expect!(Err("expect error"), "Some values: {}, {}", 1, 2); }