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
use std::{
    any::Any,
    fmt::{Debug, Display, Result},
};

#[derive(Debug)]
pub enum ErrorKind {
    PoolEnded,
    ResultAlreadyTaken,
    TimeOut,
    TaskRejected,
    Panic,
}

#[derive(Debug)]
pub struct ExecutorError {
    kind: ErrorKind,
    message: String,
    cause: Option<Box<dyn Any + Send>>,
}

impl Display for ErrorKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result {
        let msg = match self {
            ErrorKind::PoolEnded => "PoolEnded",
            ErrorKind::ResultAlreadyTaken => "ResultAlreadyTaken",
            ErrorKind::TaskRejected => "TaskRejected",
            ErrorKind::TimeOut => "TimeOUt",
            ErrorKind::Panic => "Panic",
        };
        write!(f, "{:?}", msg)
    }
}

impl ExecutorError {
    pub(crate) fn new(kind: ErrorKind, message: String) -> ExecutorError {
        ExecutorError {
            kind,
            message,
            cause: None,
        }
    }

    pub(crate) fn with_cause(
        kind: ErrorKind,
        message: String,
        cause: Box<dyn Any + Send>,
    ) -> ExecutorError {
        ExecutorError {
            kind,
            message,
            cause: Some(cause),
        }
    }

    pub fn kind(&self) -> &ErrorKind {
        &self.kind
    }

    pub fn message(&self) -> &String {
        &self.message
    }

    pub fn cause(&self) -> &Option<Box<dyn Any + Send>> {
        &self.cause
    }
}

impl Display for ExecutorError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result {
        write!(
            f,
            "ExecutorError [kind: {}, message: {}]",
            self.kind, self.message
        )
    }
}