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
use std::{
    backtrace::Backtrace,
    ops::{ControlFlow, Deref, DerefMut, FromResidual, Try},
};

use crate::print_backtrace;

pub struct Result<T, E> {
    inner: std::result::Result<T, E>,
    backtrace: Backtrace,
}

impl<T, E> Result<T, E> {
    pub fn backtrace(&self) {
        print_backtrace(&self.backtrace);
    }
}

impl<T, E> FromResidual for Result<T, E> {
    fn from_residual(residual: <Self as Try>::Residual) -> Self {
        Result {
            inner: Err(residual.0),
            backtrace: residual.1,
        }
    }
}

impl<T, E> Try for Result<T, E> {
    type Output = T;
    type Residual = (E, Backtrace);

    fn from_output(output: Self::Output) -> Self {
        Result {
            inner: Ok(output),
            backtrace: Backtrace::capture(),
        }
    }

    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
        match self.inner {
            Ok(x) => ControlFlow::Continue(x),
            Err(e) => ControlFlow::Break((e, self.backtrace)),
        }
    }
}

impl<T, E> Deref for Result<T, E> {
    type Target = std::result::Result<T, E>;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl<T, E> DerefMut for Result<T, E> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.inner
    }
}

impl<T, E> From<std::result::Result<T, E>> for Result<T, E> {
    fn from(value: std::result::Result<T, E>) -> Self {
        Self {
            inner: value,
            backtrace: Backtrace::capture(),
        }
    }
}

/*
pub trait TraceResult<T, E> {
    fn trace(self) -> Result<T, E>;
}

impl<T, E> TraceResult<T, E> for std::result::Result<T, E> {
    fn trace(self) -> Result<T, E> {
        Result {
            inner: self,
            backtrace: Backtrace::capture(),
        }
    }
}
*/