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
#[derive(Debug)]
pub enum Error {
Connect(std::io::Error),
Register(Box<Self>),
Write(std::io::Error),
Read(std::io::Error),
InvalidMessage(String),
InvalidRegistration,
EmptyChannelName,
CannotRead,
CapabilityRequired(Vec<crate::Capability>),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Connect(err) => write!(f, "cannot connect: {}", err),
Error::Register(err) => write!(f, "cannot send initial registration: {}", err),
Error::Write(err) => write!(f, "cannot write: {}", err),
Error::Read(err) => write!(f, "cannot read: {}", err),
Error::InvalidMessage(raw) => {
write!(f, "invalid message, from '{}' (trimmed)", raw.trim())
}
Error::InvalidRegistration => {
write!(f, "invalid registration. check the `token` and `nick`")
}
Error::EmptyChannelName => write!(f, "empty channel name provided"),
Error::CannotRead => write!(f, "cannot read, client should quit now"),
Error::CapabilityRequired(list) => {
let caps = list
.iter()
.map(|f| format!("{:?}", f))
.collect::<Vec<_>>()
.join(", ");
write!(f, "{} are required to do that", caps)
}
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Connect(err) | Error::Write(err) | Error::Read(err) => {
Some(err as &(dyn std::error::Error))
}
Error::Register(err) => Some(err as &(dyn std::error::Error)),
_ => None,
}
}
}