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
//! *There is nothing at all in your return type, useful or otherwise.* //! //! Proc macro attribute for a more customizable alternative to the standard library's //! `Termination` trait. //! //! As a simple example, this replicates the standard behavior for `fn main()` returning //! `Result<T, E>`: //! ```should_panic //! # #[derive(Debug)] //! # enum Error { //! # Failed, //! # } //! use whaterror::whaterror; //! //! #[whaterror(|err| eprintln!("Error: {:#?}", err))] //! fn main() -> Result<(), Error> { //! Err(Error::Failed) //! } //! ``` //! //! If your handler returns, `whaterror` will automatically exit with code 1 (or panic if inside a //! test). //! //! This also works for `Option<T>`: //! ```should_panic //! use whaterror::whaterror; //! //! #[whaterror(|| eprintln!("returned None"))] //! fn main() -> Option<()> { //! None //! } //! ``` //! //! The `||` isn't necessary in this case, since there are no arguments: //! ``` //! use whaterror::whaterror; //! //! #[whaterror(unreachable!())] //! fn main() -> Option<()> { //! Some(()) //! } //! ``` //! //! This works for non-`()` types just like you would expect. Non-`main` functions are technically //! allowed, but currently have very strict limitations. //! These limitations are planned to be lifted in the future. #![warn(missing_docs)] pub mod option; pub mod result; mod unit; #[doc(transparent)] pub use whaterror_macros::*; /// Represents an error to be handled by `whaterror`. pub trait FatalError<T> { /// Handle the error using the provided handler. fn handle(self, handler: T); } /// Represents a return value to be handled by `whaterror`. pub trait Termination { /// Type for a successful result. type Ok; /// Type for an unsuccessful result. This should implement FatalError<T> for at least one type. type Err; /// Convert to a Result<T> for handling. fn into_result(self) -> Result<Self::Ok, Self::Err>; } /// USED BY MACRO, NOT PUBLIC API #[doc(hidden)] pub fn terminate(test: bool) -> ! { if test { panic!() } else { std::process::exit(1) } }