tool/
monad.rs

1//! Useful traits and functions for working with monads (`Option`/`Result`).
2
3use core::fmt::Debug;
4
5/// Useful functions exported by `tool::monad`.
6pub mod prelude {
7    #[doc(inline)]
8    pub use super::{ok, unwrap};
9}
10
11/// Abstracts over unwrapping.
12pub trait Unwrap {
13    type Value;
14    fn unwrap(self) -> Self::Value;
15}
16
17/// Types of values that can be "Ok".
18///
19/// Basically, any type with a success variant and some number of non-success variants.
20pub trait Ok {
21    type Value;
22    fn ok(self) -> Option<Self::Value>;
23}
24
25/// Converts `Result`-like values into `Option`s.
26///
27/// ```rust
28/// use tool::ok;
29/// let filtered: Vec<_> = vec![Ok(1), Err("bad")].into_iter().filter_map(ok).collect();
30/// assert_eq!(filtered, vec![1]);
31/// ```
32pub fn ok<R: Ok>(result: R) -> Option<R::Value> {
33    result.ok()
34}
35
36/// Unwraps the value.
37///
38/// ```rust
39/// use tool::unwrap;
40/// let unwrapped: Vec<_> = vec![Result::Ok::<i32, ()>(1)].into_iter().map(unwrap).collect();
41/// assert_eq!(unwrapped, vec![1]);
42/// let unwrapped2: Vec<_> = vec![Some(2)].into_iter().map(unwrap).collect();
43/// assert_eq!(unwrapped2, vec![2]);
44/// ```
45pub fn unwrap<U: Unwrap>(unwrappable: U) -> U::Value {
46    unwrappable.unwrap()
47}
48
49impl<T> Unwrap for Option<T> {
50    type Value = T;
51    fn unwrap(self) -> Self::Value {
52        Option::unwrap(self)
53    }
54}
55
56impl<T, E: Debug> Unwrap for Result<T, E> {
57    type Value = T;
58    fn unwrap(self) -> Self::Value {
59        Result::unwrap(self)
60    }
61}
62
63impl<T> Ok for Option<T> {
64    type Value = T;
65    fn ok(self) -> Self {
66        self
67    }
68}
69
70impl<T, E> Ok for Result<T, E> {
71    type Value = T;
72    fn ok(self) -> Option<T> {
73        self.ok()
74    }
75}