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
/*! Like a `try` block, but automatically unwraps the result. Effectively, inside a `yolo!` block, the `?` operator functions as `unwrap()`. The `yolo!` macro uses a `try` block internally. `try` blocks are an unstable feature (as of this writing – Rust 1.43.1), so this crate is only available on nightly, and you must enable `#![feature(try_blocks)]` in the crate where you use it. A single `yolo!` block can handle multiple error types. Those error types can be any type that implements Debug. No extra type annotations are needed. # Examples ``` #![feature(try_blocks)] use yolo_block::yolo; use std::convert::TryFrom; let result = yolo! { "1".parse::<usize>()? + usize::try_from(2i32)? + [0,1,2,3].binary_search(&3)? }; assert_eq!(result, 6); ``` ```should_panic # #![feature(try_blocks)] # use yolo_block::yolo; // Panics with the message "YOLO'd an error: ParseIntError { kind: InvalidDigit }" let result = yolo! { "1".parse::<usize>()? + "foo".parse::<usize>()? + "3".parse::<usize>()? }; ``` **/ #![feature(track_caller)] #![no_std] #![doc(html_root_url = "https://docs.rs/yolo-block/0.1.0")] use core::convert::From; use core::fmt::Debug; // This type might be useful for users in the future - // so you could write a function that returns `Result<T, YoloError>` - // but it can't implement Error, and without that trait, // you'd run into gotchas if you tried to use ? on THAT result // in an outer function that returned Result<U, Box<dyn Error>>. // // Right now, it can't implement Debug, and hence can't implement Error, // because of a conflict with the blanket impl of From<T> for T. // Even #![feature(specialization)] can't resolve this. // // Given the gotchas, we're not making this available in the public API // until/unless we find a cleaner approach. #[doc(hidden)] pub enum YoloError {} impl<T: Debug> From<T> for YoloError { // same rationale for these attributes as for unwrap_failed() from core/result.rs #[inline(never)] #[cold] #[track_caller] fn from(t: T) -> YoloError { panic!("YOLO'd an error: {:?}", t) } } /** The macro to create a `yolo!` block. See the [crate level docs](../yolo_block/index.html) for details. **/ #[macro_export] macro_rules! yolo { ($($contents:tt)*) => {{ let result: ::core::result::Result<_, $crate::YoloError> = try { $($contents)* }; // Note: The second match arm won't be needed here once the // compiler gets smarter about uninhabited types. match result { ::core::result::Result::Ok(r) => r, ::core::result::Result::Err(e) => match e {}, } }} }