async_circe/commands.rs
1//! IRC commands
2//! - commands that can be recived from a server
3//! - commands that can be send to the server
4
5#[doc(hidden)]
6#[derive(Debug)]
7pub enum CapMode {
8 LS,
9 END,
10}
11
12/// Commands that can be send or recived from an IRC server.
13#[derive(Debug)]
14pub enum Command {
15 // TODO:
16 // SERVICE <nickname> <reserved> <distribution> <type> <reserved> <info>
17 // SQUIT <server> <comment>
18 //
19 /// Request information about the admin of a given server.
20 /// ```run_fut
21 /// # let config = Default::default();
22 /// # let mut client = Client::new(config).await?;
23 /// # client.identify().await?;
24 /// client.admin("libera.chat").await?;
25 /// # Ok(())
26 /// ```
27 /// # Errors
28 /// Returns IO errors from the TcpStream.
29 ADMIN(
30 /// Target
31 String,
32 ),
33 /// Set the status of the client.
34 /// ```run_fut
35 /// # let config = Default::default();
36 /// # let mut client = Client::new(config).await?;
37 /// # client.identify().await?;
38 /// client.away("afk").await?;
39 /// # Ok(())
40 /// ```
41 AWAY(
42 /// Message
43 String,
44 ),
45 #[doc(hidden)]
46 CAP(CapMode),
47 /// Invite someone to a channel.
48 /// ```run_fut
49 /// # let config = Default::default();
50 /// # let mut client = Client::new(config).await?;
51 /// # client.identify().await?;
52 /// client.invite("liblemonirc", "#async-circe").await?;
53 /// # Ok(())
54 /// ```
55 INVITE(
56 /// User
57 String,
58 /// Channel
59 String,
60 ),
61 /// Join a channel.
62 /// ```run_fut
63 /// # let config = Default::default();
64 /// # let mut client = Client::new(config).await?;
65 /// # client.identify().await?;
66 /// client.join("#chaos").await?;
67 /// # Ok(())
68 /// ```
69 JOIN(
70 /// Channel
71 String,
72 ),
73 /// List available channels on an IRC, or users in a channel.
74 /// ```run_fut
75 /// # let config = Default::default();
76 /// # let mut client = Client::new(config).await?;
77 /// # client.identify().await?;
78 /// client.list(None, None).await?;
79 /// # Ok(())
80 /// ```
81 LIST(
82 /// Channel
83 Option<String>,
84 /// Server to foreward request to
85 Option<String>,
86 ),
87 /// Set the mode for a user.
88 /// ```run_fut
89 /// # let config = Default::default();
90 /// # let mut client = Client::new(config).await?;
91 /// # client.identify().await?;
92 /// client.mode("test", Some("+B")).await?;
93 /// # Ok(())
94 /// ```
95 MODE(
96 /// Channel
97 String,
98 /// Mode
99 Option<String>,
100 ),
101 /// Get all the people online in channels.
102 /// ```run_fut
103 /// # let config = Default::default();
104 /// # let mut client = Client::new(config).await?;
105 /// # client.identify().await?;
106 /// client.names("#chaos,#async-circe", None).await?;
107 /// # Ok(())
108 /// ```
109 NAMES(
110 /// Channel
111 String,
112 /// Server to foreward request to
113 Option<String>,
114 ),
115 /// Change your nickname on a server.
116 /// ```run_fut
117 /// # let config = Default::default();
118 /// # let mut client = Client::new(config).await?;
119 /// # client.identify().await?;
120 /// client.nick("Not async-circe").await?;
121 /// # Ok(())
122 /// ```
123 NICK(
124 /// Nickname
125 String,
126 ),
127 /// Authentificate as an operator on a server.
128 /// ```run_fut
129 /// # let config = Default::default();
130 /// # let mut client = Client::new(config).await?;
131 /// # client.identify().await?;
132 /// client.oper("username", "password").await?;
133 /// # Ok(())
134 /// ```
135 OPER(
136 /// Username
137 String,
138 /// Password
139 String,
140 ),
141 /// Everything that is not a command
142 OTHER(String),
143 /// Leave a channel.
144 /// ```run_fut
145 /// # let config = Default::default();
146 /// # let mut client = Client::new(config).await?;
147 /// # client.identify().await?;
148 /// client.part("#chaos").await?;
149 /// # Ok(())
150 /// ```
151 PART(
152 /// Target
153 String,
154 ),
155 #[doc(hidden)]
156 PASS(String),
157 /// Tests the presence of a connection to a server.
158 /// ```run_fut
159 /// # let config = Default::default();
160 /// # let mut client = Client::new(config).await?;
161 /// # client.identify().await?;
162 /// client.ping("libera.chat", None).await?;
163 /// # Ok(())
164 /// ```
165 PING(String),
166 #[doc(hidden)]
167 PONG(String),
168 /// Send a message to a channel.
169 /// ```run_fut
170 /// # let config = Default::default();
171 /// # let mut client = Client::new(config).await?;
172 /// # client.identify().await?;
173 /// client.privmsg("#chaos", "Hello").await?;
174 /// # Ok(())
175 /// ```
176 PRIVMSG(
177 /// Source Nickname
178 String,
179 /// Channel
180 String,
181 /// Message
182 String,
183 ),
184 /// Leave the IRC server you are connected to.
185 /// ```run_fut
186 /// # let config = Default::default();
187 /// # let mut client = Client::new(config).await?;
188 /// # client.identify().await?;
189 /// client.quit(None).await?;
190 /// # Ok(())
191 /// ```
192 QUIT(
193 /// Leave message
194 String,
195 ),
196 /// Get the topic of a channel.
197 /// # Example
198 /// ```run_fut
199 /// # let config = Default::default();
200 /// # let mut client = Client::new(config).await?;
201 /// # client.identify().await?;
202 /// client.topic("#chaos", None).await?;
203 /// # Ok(())
204 /// ```
205 /// Set the topic of a channel.
206 /// # Example
207 /// ```run_fut
208 /// # let config = Default::default();
209 /// # let mut client = Client::new(config).await?;
210 /// # client.identify().await?;
211 /// client.topic("#chaos", Some("main channel")).await?;
212 /// # Ok(())
213 /// ```
214 /// # Errors
215 /// Returns IO errors from the TcpStream.
216 TOPIC(
217 /// Channel
218 String,
219 /// Topic
220 Option<String>,
221 ),
222 #[doc(hidden)]
223 USER(String, String, String, String),
224}
225
226impl Command {
227 /// Creates a Command from a `&str`. Currently only `[PING]` and `[PRIVMSG]` are supported.
228 ///
229 /// # Panics
230 /// This function will panic if the ``IRCd`` sends malformed messages. Please contact the
231 /// maintainer of your ``IRCd`` if this happens.
232 pub async fn command_from_str(s: &str) -> Self {
233 let new = s.trim();
234 tracing::trace!("{}", new);
235 let parts: Vec<&str> = new.split_whitespace().collect();
236
237 if parts.get(0) == Some(&"PING") {
238 // We can assume that [1] exists because if it doesn't then something's gone very wrong
239 // with the IRCD
240 let command = parts[1].to_string();
241 return Self::PING(command);
242 } else if parts.get(1) == Some(&"PRIVMSG") {
243 let nick_realname = parts[0];
244 let nick: String;
245
246 let index = nick_realname.chars().position(|c| c == '!');
247 if let Some(index) = index {
248 if index > 0 {
249 nick = String::from(&nick_realname[1..index]);
250 } else {
251 nick = String::new();
252 }
253 } else {
254 nick = String::new();
255 }
256
257 let target = parts[2];
258 let msg = parts[3..].join(" ");
259
260 return Self::PRIVMSG(nick, target.to_string(), (msg[1..]).to_string());
261 }
262
263 Self::OTHER(new.to_string())
264 }
265}