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
90
91
92
93
94
95
96
97
/// An invalid message was either provided, or could not be parsed
#[derive(Debug)]
#[non_exhaustive]
pub enum MessageError {
/// Invalid command
InvalidCommand {
/// Expected this command
expected: String,
/// But got this command
got: String,
},
/// Expected a nickname attached to that message
ExpectedNick,
/// Expected an argument at position `pos`
ExpectedArg {
/// 'index' of the argument (e.g. 0)
pos: usize,
},
/// expected data attached to that message
ExpectedData,
/// Expected a specific tag
ExpectedTag {
/// The tag name
name: String,
},
/// Cannot parse a specific tag
CannotParseTag {
/// The tag name
name: String,
/// The parse error
error: Box<dyn std::error::Error + Send + Sync>,
},
/// An empty key in the tags was provided
MissingTagKey(
/// Tag pair index this key was expected to be at
usize,
),
/// A value wasn't provided for a tag pair
///
/// This usually means the tag was 'key;' and not 'key=val'. 'key=' is allowed.
MissingTagValue(
/// Tag pair index this key was expected to be at
usize,
),
/// An incomplete message was provided
IncompleteMessage {
/// At index `pos`
pos: usize,
},
/// An empty message was provided
EmptyMessage,
/// A custom error message
Custom {
/// The inner error
error: Box<dyn std::error::Error + Send + Sync>,
},
}
impl std::fmt::Display for MessageError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::InvalidCommand { expected, got } => {
write!(f, "invalid command. expected '{}' got '{}'", expected, got)
}
Self::ExpectedNick => write!(f, "expected a nickname attached to that message"),
Self::ExpectedArg { pos } => write!(f, "expected arg at position: {}", pos),
Self::ExpectedData => write!(f, "expected a data segment in the message"),
Self::ExpectedTag { name } => write!(f, "expected tag '{}'", name),
Self::CannotParseTag { name, error } => write!(f, "cannot parse '{}': {}", name, error),
Self::MissingTagKey(index) => write!(f, "missing tag key at pair index: {}", index),
Self::MissingTagValue(index) => write!(f, "missing tag value at pair index: {}", index),
Self::IncompleteMessage { pos } => write!(f, "incomplete message starting at: {}", pos),
Self::EmptyMessage => write!(f, "no message could be parsed"),
Self::Custom { error } => write!(f, "custom error: {}", error),
}
}
}
impl std::error::Error for MessageError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::CannotParseTag { error, .. } => Some(&**error),
Self::Custom { error } => Some(&**error),
_ => None,
}
}
}