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
use std::{fmt, sync::Arc};

use kanal::{ReceiveError, SendError};

use crate::message::ErrorMessage;

#[derive(Debug)]
pub enum Error {
    HandlerIsNotRegistered,
    Aborted,
    SendError(SendError),
    ReceiveError(kanal::ReceiveError),
    ReorderingDropMessage(u64, u64),
    HandlerError(Arc<dyn ErrorMessage>),
}

#[derive(Debug)]
pub enum VoidError {}
impl std::fmt::Display for VoidError {
    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
        Ok(())
    }
}

impl std::error::Error for Error {}
impl ErrorMessage for VoidError {}

impl Eq for Error {}

impl PartialEq for Error {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Error::HandlerIsNotRegistered, Error::HandlerIsNotRegistered) => true,
            (Error::Aborted, Error::Aborted) => true,
            (Error::SendError(err1), Error::SendError(err2)) => err1.eq(err2),
            (Error::ReceiveError(err1), Error::ReceiveError(err2)) => err1.eq(err2),
            (Error::ReorderingDropMessage(idx1, e1), Error::ReorderingDropMessage(idx2, e2)) => {
                idx1.eq(idx2) && e1.eq(e2)
            }
            (Error::HandlerError(err1), Error::HandlerError(err2)) => Arc::ptr_eq(err1, err2),
            _ => false,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::HandlerError(err) => writeln!(f, "Handler Error: {err}")?,
            Error::HandlerIsNotRegistered => writeln!(f, "Handle is not registered!")?,
            Error::Aborted => writeln!(f, "Operation Aborted!")?,
            Error::SendError(reason) => writeln!(f, "Channel send error; reason {reason}")?,
            Error::ReceiveError(reason) => writeln!(f, "Channel receive error; reason {reason}")?,
            Error::ReorderingDropMessage(index, expected) => {
                writeln!(f, "Reordering drop message #{index} expected #{expected}")?
            }
        }

        Ok(())
    }
}

impl Clone for Error {
    fn clone(&self) -> Self {
        match self {
            Error::HandlerError(err) => Error::HandlerError(err.clone()),
            Error::SendError(err) => match err {
                SendError::Closed => Error::SendError(SendError::Closed),
                SendError::ReceiveClosed => Error::SendError(SendError::ReceiveClosed),
            },
            Error::ReceiveError(err) => match err {
                ReceiveError::Closed => Error::ReceiveError(ReceiveError::Closed),
                ReceiveError::SendClosed => Error::ReceiveError(ReceiveError::SendClosed),
            },
            Error::HandlerIsNotRegistered => Error::HandlerIsNotRegistered,
            Error::Aborted => Error::Aborted,
            Error::ReorderingDropMessage(idx, e) => Error::ReorderingDropMessage(*idx, *e),
        }
    }
}

impl<E> From<E> for Error
where
    E: ErrorMessage,
{
    fn from(error: E) -> Self {
        Self::HandlerError(Arc::new(error))
    }
}