1#![cfg_attr(feature = "no_std", no_std)]
2
3use core::fmt::{Debug, Display};
4
5pub mod prelude {
17 pub use crate::{OptionOrPanic, ResultOrPanic};
18}
19
20pub trait OptionOrPanic<T> {
21 #[track_caller]
27 fn or_panic<M: Display>(self, msg: M) -> T;
28}
29
30impl<T> OptionOrPanic<T> for Option<T> {
31 #[track_caller]
32 fn or_panic<M: Display>(self, msg: M) -> T {
33 self.unwrap_or_else(|| panic!("{msg}"))
34 }
35}
36
37pub trait ResultOrPanic<T> {
38 #[track_caller]
46 fn or_panic<M: Display>(self, msg: M) -> T;
47}
48
49impl<T, E: Debug> ResultOrPanic<T> for Result<T, E> {
50 #[track_caller]
51 fn or_panic<M: Display>(self, msg: M) -> T {
52 self.unwrap_or_else(|err| panic!("{msg}.\nCaused by: {err:?}"))
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn option_or_panic_returns_value() {
62 let x = Some(42).or_panic("should not panic");
63 assert_eq!(x, 42);
64 }
65
66 #[test]
67 #[should_panic(expected = "option is missing")]
68 fn option_or_panic_panics_on_none() {
69 let x: Option<i32> = None;
70 x.or_panic("option is missing");
71 }
72
73 #[test]
74 #[should_panic(expected = "error 123")]
75 fn option_or_panic_handles_display_types() {
76 let x: Option<i32> = None;
77 let code = 123;
78 x.or_panic(format!("error {code}"));
79 }
80
81 #[test]
82 fn result_or_panic_returns_ok_value() {
83 let r: Result<i32, &str> = Ok(7);
84 let x = r.or_panic("no panic expected");
85 assert_eq!(x, 7);
86 }
87
88 #[test]
89 #[should_panic(expected = "explicit failure.\nCaused by: \"boom\"")]
90 fn result_or_panic_panics_on_err() {
91 let r: Result<i32, &str> = Err("boom");
92 r.or_panic("explicit failure");
93 }
94
95 #[test]
96 #[should_panic(expected = "Bad stuff.\nCaused by: 404")]
97 fn result_or_panic_works_with_display_formatting() {
98 let r: Result<i32, i32> = Err(404);
99 r.or_panic("Bad stuff");
100 }
101
102 #[test]
103 fn result_or_panic_allows_non_string_message_types() {
104 let r: Result<&str, &str> = Ok("yay");
105 let msg_int = 999; let v = r.or_panic(msg_int);
108 assert_eq!(v, "yay");
109 }
110}