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
/// struct created for error handling
/// 
/// # Examples
/// ```
/// use cursederror::*;
/// 
/// fn devide(a: i32, b: i32) -> Result<i32, CursedErrorHandle> {
///     if b == 0 {
///         return Err(CursedErrorHandle::new(
///             CursedError::InvalidArgument,
///             "0 devision!!!".to_string()
///         ))
///     }
/// 
///     Ok(a/b)
/// }
/// 
/// let result = devide(6, 3).expect("devision error");
/// 
/// assert_eq!(result, 2)
/// ```
pub struct CursedErrorHandle {
    error: CursedError,
    reason: String,
}

impl CursedErrorHandle {
    pub fn new(error: CursedError, reason: String) -> Self {
        Self { error, reason }
    }
    pub fn get_error(&self) -> &CursedError {
        &self.error
    }
    pub fn get_reason(&self) -> &String {
        &self.reason
    }
}

impl std::fmt::Display for CursedErrorHandle {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{} kind error: \"{}\"", self.error.debug(), self.reason)
    }
}
impl std::fmt::Debug for CursedErrorHandle {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_tuple(self.error.debug())
            .field(&self.reason)
            .finish()
    }
}
impl std::error::Error for CursedErrorHandle {}

/// enum with kinds of errors
pub enum CursedError {
    InvalidArgument,
    InvalidCommand,
    InvalidOption,
    Initialize,
    ThreadJoin,
    NotEnought,
    TimeOut,
    Sockets,
    TooMany,
    Parse,
    OS
}

impl CursedError {
    pub fn debug(&self) -> &'static str {
        match *self {
            CursedError::InvalidArgument => "invalid argument",
            CursedError::InvalidCommand => "invalid command",
            CursedError::InvalidOption => "invalid option",
            CursedError::Initialize => "initialize",
            CursedError::ThreadJoin => "thread join",
            CursedError::NotEnought => "not enought",
            CursedError::TimeOut => "time out",
            CursedError::Sockets => "sockets",
            CursedError::TooMany => "too many",
            CursedError::Parse => "parse",
            CursedError::OS => "OS",
        }
    }
}