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 {}