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}