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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::borrow::Cow;
use crate::{Error, Parse};
/// The kind of the [`Message`](crate::messages::Message)
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
pub enum MessageKind<'a> {
/// [`Capability`](super::messages::Capability)
Capability,
/// [`Ping`](super::messages::Ping)
Ping,
/// [`Pong`](super::messages::Pong)
Pong,
/// [`IrcReady`](super::messages::IrcReady)
IrcReady,
/// [`Ready`](super::messages::Ready)
Ready,
/// [`GlobalUserState`](super::messages::GlobalUserState)
GlobalUserState,
/// [`UserState`](super::messages::UserState)
UserState,
/// [`RoomState`](super::messages::RoomState)
RoomState,
/// [`Privmsg`](super::messages::Privmsg)
Privmsg,
/// [`ClearChat`](super::messages::ClearChat)
ClearChat,
/// [`ClearMsg`](super::messages::ClearMsg)
ClearMsg,
/// [`Notice`](super::messages::Notice)
Notice,
/// [`HostTarget`](super::messages::HostTarget)
HostTarget,
/// [`UserNotice`](super::messages::UserNotice)
UserNotice,
/// [`Whisper`](super::messages::Whisper)
Whisper,
/// [`Reconnect`](super::messages::Reconnect)
Reconnect,
/// IRC Numeric
Numeric(u16),
/// An unknown message kind
Unknown(Cow<'a, str>),
}
impl MessageKind<'_> {
pub(crate) const fn as_str(&self) -> &'static str {
match self {
Self::Capability => "Capability",
Self::Ping => "Ping",
Self::Pong => "Pong",
Self::IrcReady => "IrcReady",
Self::Ready => "Ready",
Self::GlobalUserState => "GlobalUserState",
Self::UserState => "UserState",
Self::RoomState => "RoomState",
Self::Privmsg => "Privmsg",
Self::ClearChat => "ClearChat",
Self::ClearMsg => "ClearMsg",
Self::Notice => "Notice",
Self::HostTarget => "HostTarget",
Self::UserNotice => "UserNotice",
Self::Whisper => "Whisper",
Self::Reconnect => "Reconnect",
Self::Numeric(_) => "Numeric",
Self::Unknown(_) => "Unknown",
}
}
}
impl<'a> Parse<'a> for MessageKind<'a> {
type Output = Result<Self, Error>;
fn parse(input: &mut &'a str) -> Self::Output {
let head = match input.split_once(' ') {
Some((head, tail)) => {
*input = tail;
head
}
None => {
let head = *input;
*input = "";
head
}
};
let kind = match head {
"CAP" => Self::Capability,
"PING" => Self::Ping,
"PONG" => Self::Pong,
"001" => Self::IrcReady,
"376" => Self::Ready,
"GLOBALUSERSTATE" => Self::GlobalUserState,
"USERSTATE" => Self::UserState,
"ROOMSTATE" => Self::RoomState,
"PRIVMSG" => Self::Privmsg,
"NOTICE" => Self::Notice,
"CLEARCHAT" => Self::ClearChat,
"CLEARMSG" => Self::ClearMsg,
"HOSTTARGET" => Self::HostTarget,
"USERNOTICE" => Self::UserNotice,
"WHISPER" => Self::Whisper,
"RECONNECT" => Self::Reconnect,
s if s.chars().all(|c| c.is_ascii_digit()) => {
Self::Numeric(s.parse().map_err(|_| Error::InvalidNumeric)?)
}
unknown => Self::Unknown(Cow::from(unknown)),
};
Ok(kind)
}
}