valust_utils/dangerous.rs
1//! **Dangerous** functions that might cause a panic.
2
3#![allow(private_bounds, private_interfaces)]
4
5use std::fmt::Debug;
6
7use sealed::sealed;
8
9/// This trait is implemented for `Option` and `Result` types.
10///
11/// This trait is **sealed**.
12#[sealed]
13pub trait Unwrap {
14 /// Out type of the `unwrap` operation.
15 ///
16 /// This will be `T` for `Option<T>` and `Result<T, E>`.
17 type Out;
18
19 #[allow(missing_docs)]
20 fn unwrap(self) -> Self::Out;
21
22 #[allow(missing_docs)]
23 fn expect(self, msg: &str) -> Self::Out;
24}
25
26#[sealed]
27impl<T> Unwrap for Option<T> {
28 type Out = T;
29
30 fn unwrap(self) -> Self::Out {
31 Option::unwrap(self)
32 }
33
34 fn expect(self, msg: &str) -> Self::Out {
35 Option::expect(self, msg)
36 }
37}
38
39#[sealed]
40impl<T, E: Debug> Unwrap for Result<T, E> {
41 type Out = T;
42
43 fn unwrap(self) -> Self::Out {
44 Result::unwrap(self)
45 }
46
47 fn expect(self, msg: &str) -> Self::Out {
48 Result::expect(self, msg)
49 }
50}
51
52/// Unwrap an `Option` or `Result`.
53///
54/// This might cause a panic, use carefully.
55///
56/// ```rust
57/// # use valust_utils::dangerous::unwrap;
58/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
59/// # use valust_derive::Valust;
60/// #
61/// #[derive(Valust)]
62/// struct MustBeSome(
63/// #[trans(func(Option<i32> => unwrap))]
64/// i32,
65/// );
66/// ```
67pub fn unwrap<T: Unwrap>(t: T) -> T::Out {
68 t.unwrap()
69}
70
71/// Unwrap an `Option` or `Result` with a custom message.
72///
73/// This might cause a panic, use carefully.
74///
75/// ```rust
76/// # use valust_utils::dangerous::expect;
77/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
78/// # use valust_derive::Valust;
79/// #
80/// #[derive(Valust)]
81/// struct MustBeSome(
82/// #[trans(func(Option<i32> => expect("must be some")))]
83/// i32,
84/// );
85/// ```
86pub fn expect<T: Unwrap>(msg: &str) -> impl Fn(T) -> T::Out + '_ {
87 move |t| t.expect(msg)
88}