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
//! This crate provides a macro similar to the old `try!` macro, or to the `?`, except it wraps //! the error in something else. //! //! This is useful if you want to use a `?` for easily returning say, invalid input errors, //! but you can't do so because you have an additional `Result` level for handling internal errors of a different nature. //! //! This macro allows you to do so: //! //! ```ignore //! fn foo(input: Input) -> Result<Result<FinalOutput, InvalidInputError>, DatabaseError> { //! let validated_input: ValidatedInput = try_or_wrap!(validate_input_with_database(input)?, Ok); //! Ok(Ok(do_stuff_with_validated_input(validated_input)?)) //! } //! //! fn validate_input_with_database(input: Input) -> Result<Result<ValidatedInput, InvalidInputError>, DatabaseError>; //! ``` #[macro_export] /// Helper macro to wrap `?` into something else, for `Result` /// /// # Example /// ```ignore /// fn foo(input: Input) -> Result<Result<FinalOutput, InvalidInputError>, DatabaseError> { /// let validated_input: ValidatedInput = try_or_wrap!(validate_input_with_database(input)?, Ok); /// Ok(Ok(do_stuff_with_validated_input(validated_input)?)) /// } /// /// fn validate_input_with_database(input: Input) -> Result<Result<ValidatedInput, InvalidInputError>, DatabaseError>; /// ```` /// /// Note that the `Ok` parameter as shown in this example is optional, as it defaults to `Ok` if unspecified. macro_rules! try_or_wrap { ($expr:expr) => { try_or_wrap! { $expr, Ok } }; ($expr:expr, $wrapper:expr) => { match $expr { std::result::Result::Ok(val) => val, std::result::Result::Err(err) => { return $wrapper(std::result::Result::Err(std::convert::Into::into(err))) } } }; } /// Same as `try_or_wrap`, but for `Option` #[macro_export] macro_rules! try_or_wrap_opt { ($expr:expr) => { try_or_wrap_opt! { $expr, Ok } }; ($expr:expr, $wrapper:expr) => { match $expr { std::option::Option::Some(val) => val, std::option::Option::None => return $wrapper(std::option::Option::None), } }; }