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}