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
use std::clone::Clone;
use std::marker::Send;
use std::thread;

pub trait TapRef<T, E> {
    fn tap_ref<F: FnOnce(&T)>(self, op: F) -> Result<T, E>;
}

pub trait Tap<T, E> {
    fn tap<F: FnOnce(T)>(self, op: F) -> Result<T, E>;
}
pub trait TapClone<T, E> {
    fn tap<F: FnOnce(T)>(self, op: F) -> Result<T, E>;
}

pub trait TapErr<T, E> {
    fn tap_err<F: FnOnce(E)>(self, op: F) -> Result<T, E>;
}
pub trait TapErrRef<T, E> {
    fn tap_err_ref<F: FnOnce(&E)>(self, op: F) -> Result<T, E>;
}

pub trait ThreadTap<T, E> {
    fn thread_tap<F: 'static + FnOnce(T) + Send>(self, op: F) -> Result<T, E>;
}
pub trait ThreadTapErr<T, E> {
    fn thread_tap_err<F: 'static + FnOnce(E) + Send>(self, op: F) -> Result<T, E>;
}

impl<T, E> TapRef<T, E> for Result<T, E> {
    fn tap_ref<F: FnOnce(&T)>(self, op: F) -> Result<T, E> {
        if let Ok(ref ok) = self {
            op(&ok);
        }
        self
    }
}

impl<T: Clone, E> TapClone<T, E> for Result<T, E> {
    fn tap<F: FnOnce(T)>(self, op: F) -> Result<T, E> {
        if let Ok(ref ok) = self {
            op(ok.clone());
        }
        self
    }
}

impl<T, E: std::clone::Clone> TapErr<T, E> for Result<T, E> {
    fn tap_err<F: FnOnce(E)>(self, op: F) -> Result<T, E> {
        if let Err(ref err) = self {
            op(err.clone());
        }
        self
    }
}

impl<T, E> TapErrRef<T, E> for Result<T, E> {
    fn tap_err_ref<F: FnOnce(&E)>(self, op: F) -> Result<T, E> {
        if let Err(ref err) = self {
            op(err);
        }
        self
    }
}

impl<T: 'static + Clone + Send, E> ThreadTap<T, E> for Result<T, E> {
    fn thread_tap<'a, F: 'static + FnOnce(T) + Send>(self, op: F) -> Result<T, E> {
        match self {
            Ok(ok) => {
                let new_ok = ok.clone();
                thread::spawn(move || op(new_ok));
                Ok(ok)
            }
            _ => self,
        }
    }
}

impl<T, E: 'static + Clone + Send> ThreadTapErr<T, E> for Result<T, E> {
    fn thread_tap_err<F: 'static + FnOnce(E) + Send>(self, op: F) -> Result<T, E> {
        match self {
            Err(err) => {
                let new_err = err.clone();
                thread::spawn(move || op(new_err));
                Err(err)
            }
            _ => self,
        }
    }
}