debugless_unwrap/lib.rs
1//! This library provides alternatives to the standard `.unwrap`* methods on `Result` and `Option` that don't require `Debug` to be implemented on the unexpected variant.
2//!
3//! # Example
4//!
5//! Given
6//!
7//! ```
8//! struct T;
9//!
10//! let none = Option::<T>::None;
11//! let ok = Result::<T, T>::Ok(T);
12//! let err = Result::<T, T>::Err(T);
13//! ```
14//!
15//! , the following `std` methods are unavailable:
16//!
17//! ```compile_fail
18//! # struct T;
19//! # let none = Option::<T>::None;
20//! # let ok = Result::<T, T>::Ok(T);
21//! # let err = Result::<T, T>::Err(T);
22//! #
23//! none.unwrap_none(); // Some(T) isn't Debug.
24//! ```
25//!
26//! ```compile_fail
27//! # struct T;
28//! # let none = Option::<T>::None;
29//! # let ok = Result::<T, T>::Ok(T);
30//! # let err = Result::<T, T>::Err(T);
31//! #
32//! ok.unwrap(); // Err(T) isn't Debug.
33//! ```
34//!
35//! ```compile_fail
36//! # struct T;
37//! # let none = Option::<T>::None;
38//! # let ok = Result::<T, T>::Ok(T);
39//! # let err = Result::<T, T>::Err(T);
40//! #
41//! err.unwrap_err(); // Ok(T) isn't Debug.
42//! ```
43//!
44//! The methods in this library can be used in this situation (e.g. when working with generics), but provide less information:
45//!
46//! Additionally given
47//!
48//! ```
49//! use debugless_unwrap::*;
50//! ```
51//!
52//! , the following work like their `debugless_`-less equivalents:
53//!
54//! ```
55//! # use debugless_unwrap::*;
56//! # struct T;
57//! # let none = Option::<T>::None;
58//! # let ok = Result::<T, T>::Ok(T);
59//! # let err = Result::<T, T>::Err(T);
60//! #
61//! none.debugless_unwrap_none();
62//! ```
63//!
64//! ```
65//! # use debugless_unwrap::*;
66//! # struct T;
67//! # let none = Option::<T>::None;
68//! # let ok = Result::<T, T>::Ok(T);
69//! # let err = Result::<T, T>::Err(T);
70//! #
71//! ok.debugless_unwrap();
72//! ```
73//!
74//! ```
75//! # use debugless_unwrap::*;
76//! # struct T;
77//! # let none = Option::<T>::None;
78//! # let ok = Result::<T, T>::Ok(T);
79//! # let err = Result::<T, T>::Err(T);
80//! #
81//! err.debugless_unwrap_err();
82//! ```
83
84#![no_std]
85#![warn(clippy::pedantic)]
86
87/// Provides `.debugless_unwrap()` on `Result`.
88///
89/// # Example
90///
91/// ```
92/// use assert_panic::assert_panic;
93/// use debugless_unwrap::DebuglessUnwrapExt;
94///
95/// struct T;
96///
97/// let ok = Result::<T, T>::Ok(T);
98/// let err = Result::<T, T>::Err(T);
99///
100/// ok.debugless_unwrap();
101///
102/// assert_panic!({ err.debugless_unwrap(); });
103/// ```
104pub trait DebuglessUnwrapExt {
105 type Unwrapped;
106
107 #[track_caller]
108 fn debugless_unwrap(self) -> Self::Unwrapped;
109}
110
111impl<T, E> DebuglessUnwrapExt for Result<T, E> {
112 type Unwrapped = T;
113 fn debugless_unwrap(self) -> Self::Unwrapped {
114 if let Ok(unwrapped) = self {
115 unwrapped
116 } else {
117 panic!("Tried to debugless_unwrap Err value")
118 }
119 }
120}
121
122/// Provides `.debugless_unwrap_err()` on `Result`.
123///
124/// # Example
125///
126/// ```
127/// use assert_panic::assert_panic;
128/// use debugless_unwrap::DebuglessUnwrapErrExt;
129///
130/// struct T;
131///
132/// let ok = Result::<T, T>::Ok(T);
133/// let err = Result::<T, T>::Err(T);
134///
135/// err.debugless_unwrap_err();
136///
137/// assert_panic!({ ok.debugless_unwrap_err(); });
138/// ```
139pub trait DebuglessUnwrapErrExt {
140 type Unwrapped;
141
142 #[track_caller]
143 fn debugless_unwrap_err(self) -> Self::Unwrapped;
144}
145
146impl<T, E> DebuglessUnwrapErrExt for Result<T, E> {
147 type Unwrapped = E;
148 fn debugless_unwrap_err(self) -> Self::Unwrapped {
149 match self {
150 Ok(_) => panic!("Tried to debugless_unwrap_err Ok value"),
151 Err(unwrapped) => unwrapped,
152 }
153 }
154}
155
156/// Provides `.debugless_unwrap_none()` on `Option`.
157///
158/// # Example
159///
160/// ```
161/// use assert_panic::assert_panic;
162/// use debugless_unwrap::DebuglessUnwrapNoneExt;
163///
164/// struct T;
165///
166/// let some = Some(T);
167/// let none = Option::<T>::None;
168///
169/// none.debugless_unwrap_none();
170///
171/// assert_panic!(some.debugless_unwrap_none());
172/// ```
173pub trait DebuglessUnwrapNoneExt {
174 #[track_caller]
175 fn debugless_unwrap_none(self);
176}
177
178impl<T> DebuglessUnwrapNoneExt for Option<T> {
179 fn debugless_unwrap_none(self) {
180 assert!(self.is_none(), "Tried to debugless_unwrap_none Some value");
181 }
182}
183
184pub mod prelude {
185 pub use super::{DebuglessUnwrapErrExt, DebuglessUnwrapExt, DebuglessUnwrapNoneExt};
186}
187
188#[cfg(doctest)]
189#[doc = include_str!("../README.md")]
190pub mod readme {}