1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
pub trait TapResult<T, E> {
fn tap<F: FnOnce(&T)>(self, op: F) -> Self;
fn tap_mut<F: FnOnce(&mut T)>(self, op: F) -> Self;
fn tap_err<F: FnOnce(&E)>(self, op: F) -> Self;
fn tap_err_mut<F: FnOnce(&mut E)>(self, op: F) -> Self;
}
/// # impl of TapRef [`Result<T,E>`]
/// This allows tapping into the result object and interact with a reference of the internal data.
impl<T, E> TapResult<T, E> for Result<T, E> {
/// # tap_ref
///
/// tap mut gives an immutable reference of the underlying data.
/// this can often be used as way to log or read data in a cleaner fashion then using a map
/// where you will hate to return the data anyways even if nothing has been modified.
/// Taps does not rely on a return value.
/// ```
/// use gearbox::rails::ext::blocking::TapResult;
///
/// let res: Result<_,()> = Ok("hello".to_string());
/// res.tap(|t| assert_eq!(t, &"hello".to_string())).ok();
/// ```
#[inline]
fn tap<F: FnOnce(&T)>(self, op: F) -> Result<T, E> {
match &self {
Ok(t) => op(t),
_ => {}
}
self
}
/// # tap_mut
///
/// This allows for modifying the data that are recieved through tap.
/// Normally map will to fine in this instance, though this allows for modifying the data
/// behind the reference.
/// The difference between map and tap_mut is that it operates directly on the reference and
/// that the datatype is not allowed to change.
/// ```
/// use gearbox::rails::ext::blocking::TapResult;
///
/// let mut res: Result<_,()> = Ok("hello".to_string());
///
/// assert_eq!(res.tap_mut(|t| *t = "world".to_string()).unwrap(), "world".to_string());
/// ```
#[inline]
fn tap_mut<F: FnOnce(&mut T)>(mut self, op: F) -> Self {
match &mut self {
Ok(t) => op(t),
_ => {}
}
self
}
/// # tap_ref
///
/// tap mut gives an immutable reference of the underlying data.
/// this can often be used as way to log or read data in a cleaner fashion then using a map
/// where you will hate to return the data anyways even if nothing has been modified.
/// Taps does not rely on a return value.
/// ```
/// use gearbox::rails::ext::blocking::TapResult;
///
/// let res: Result<(),_> = Err("hello".to_string());
/// res.tap_err(|t| assert_eq!(t, &"hello".to_string())).ok();
/// ```
#[inline]
fn tap_err<F: FnOnce(&E)>(self, op: F) -> Result<T, E> {
match &self {
Err(e) => op(e),
_ => {}
}
self
}
/// # tap_mut
///
/// This allows for modifying the data that are recieved through tap.
/// Normally map will to fine in this instance, though this allows for modifying the data
/// behind the reference.
/// The difference between map and tap_mut is that it operates directly on the reference and
/// that the datatype is not allowed to change.
/// ```
/// use gearbox::rails::ext::blocking::TapResult;
///
/// let res: Result<(),_> = Err("hello".to_string());
///
/// assert_eq!(res.tap_err_mut(|t| *t = "world".to_string()).unwrap_err(), "world".to_string());
/// ```
#[inline]
fn tap_err_mut<F: FnOnce(&mut E)>(mut self, op: F) -> Self {
match &mut self {
Err(e) => op(e),
_ => {}
}
self
}
}