1use std::fmt::Formatter;
16use std::{
17 error::Error as StdError,
18 fmt::{self, Display},
19};
20
21pub type Result<T> = std::result::Result<T, Error>;
23
24type StdThreadError = dyn StdError + Send + Sync;
29
30pub struct Error {
32 repr: Repr,
33}
34
35impl StdError for Error {}
37
38#[derive(Debug)]
39enum Repr {
40 Simple(ErrorKind),
41 Custom(Box<Custom>),
42}
43
44#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
45pub enum ErrorKind {
46 InvalidPacket,
48
49 InvalidHeader,
51
52 InvalidPayload,
54
55 InvalidSURB,
57
58 InvalidRouting,
60}
61
62impl ErrorKind {
63 pub(crate) fn as_str(&self) -> &'static str {
64 match &self {
65 ErrorKind::InvalidPacket => "packet processing failure",
66 ErrorKind::InvalidHeader => "header processing failure",
67 ErrorKind::InvalidPayload => "payload processing failure",
68 ErrorKind::InvalidSURB => "SURB processing failure",
69 ErrorKind::InvalidRouting => "routing information processing failure",
70 }
71 }
72}
73
74impl From<ErrorKind> for Error {
75 fn from(kind: ErrorKind) -> Self {
76 Error {
77 repr: Repr::Simple(kind),
78 }
79 }
80}
81
82impl Display for Error {
83 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), fmt::Error> {
84 match self.repr {
85 Repr::Simple(kind) => write!(f, "{}", kind.as_str()),
86 Repr::Custom(ref c) => write!(f, "{}: {}", c.kind.as_str(), c.error),
87 }
88 }
89}
90
91impl fmt::Debug for Error {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 fmt::Debug::fmt(&self.repr, f)
94 }
95}
96
97#[derive(Debug)]
98struct Custom {
99 kind: ErrorKind,
100 error: Box<StdThreadError>,
101}
102
103impl Error {
104 pub fn new<E>(kind: ErrorKind, error: E) -> Self
105 where
106 E: Into<Box<StdThreadError>>,
107 {
108 Error {
109 repr: Repr::Custom(Box::new(Custom {
110 kind,
111 error: error.into(),
112 })),
113 }
114 }
115
116 pub fn kind(&self) -> ErrorKind {
117 match self.repr {
118 Repr::Custom(ref c) => c.kind,
119 Repr::Simple(kind) => kind,
120 }
121 }
122}