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}