Compare commits
3 commits
dde7aeb43f
...
f336537670
Author | SHA1 | Date | |
---|---|---|---|
famfo | f336537670 | ||
famfo | 041922dae8 | ||
famfo | 9be9af0a8b |
|
@ -109,8 +109,8 @@ pub enum Command {
|
|||
NAMES(
|
||||
/// Channel
|
||||
String,
|
||||
/// Server to foreward request to
|
||||
Option<String>,
|
||||
/// User
|
||||
String,
|
||||
),
|
||||
/// Change your nickname on a server.
|
||||
/// ```run_fut
|
||||
|
@ -164,15 +164,8 @@ pub enum Command {
|
|||
/// ```
|
||||
PING(String),
|
||||
#[doc(hidden)]
|
||||
PONG(String),
|
||||
/// Send a message to a channel.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.privmsg("#chaos", "Hello").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
PONG(String, String),
|
||||
/// Message send in a channel
|
||||
PRIVMSG(
|
||||
/// Source Nickname
|
||||
String,
|
||||
|
@ -219,59 +212,75 @@ pub enum Command {
|
|||
/// Topic
|
||||
String,
|
||||
),
|
||||
#[doc(hidden)]
|
||||
TopicBy(String, String),
|
||||
/// User the set the topic in a channel at a time
|
||||
TOPIC_BY(String, String),
|
||||
#[doc(hidden)]
|
||||
USER(String, String, String, String),
|
||||
}
|
||||
|
||||
impl Command {
|
||||
/// Creates a Command from a `&str`. Currently only `[PING]` and `[PRIVMSG]` are supported.
|
||||
/// Creates a Command from a `&str`. Currently `[PRIVMSG]` `[TOPIC]` `[NAMES]` and `[PONG]` are supported.
|
||||
///
|
||||
/// # Panics
|
||||
/// This function will panic if the ``IRCd`` sends malformed messages. Please contact the
|
||||
/// maintainer of your ``IRCd`` if this happens.
|
||||
pub async fn command_from_str(s: &str) -> Self {
|
||||
pub async fn command_from_str(s: String) -> Self {
|
||||
let new = s.trim();
|
||||
tracing::trace!("{}", new);
|
||||
let parts: Vec<&str> = new.split_whitespace().collect();
|
||||
|
||||
if parts.get(0) == Some(&"PING") {
|
||||
// We can assume that [1] exists because if it doesn't then something's gone very wrong
|
||||
// with the IRCD
|
||||
let command = parts[1].to_string();
|
||||
return Self::PING(command);
|
||||
} else if parts.get(1) == Some(&"PRIVMSG") {
|
||||
let nick_realname = parts[0];
|
||||
let nick: String;
|
||||
|
||||
let index = nick_realname.chars().position(|c| c == '!');
|
||||
if let Some(index) = index {
|
||||
if index > 0 {
|
||||
nick = String::from(&nick_realname[1..index]);
|
||||
return Self::PING(command);
|
||||
}
|
||||
|
||||
match parts.get(1) {
|
||||
Some(&"PRIVMSG") => {
|
||||
let nick_realname = parts[0];
|
||||
let nick: String;
|
||||
|
||||
let index = nick_realname.chars().position(|c| c == '!');
|
||||
if let Some(index) = index {
|
||||
if index > 0 {
|
||||
nick = String::from(&nick_realname[1..index]);
|
||||
} else {
|
||||
nick = String::new();
|
||||
}
|
||||
} else {
|
||||
nick = String::new();
|
||||
}
|
||||
} else {
|
||||
nick = String::new();
|
||||
|
||||
let target = parts[2];
|
||||
let msg = parts[3..].join(" ");
|
||||
|
||||
Self::PRIVMSG(nick, target.to_string(), (msg[1..]).to_string())
|
||||
}
|
||||
Some(&"331") | Some(&"332") => {
|
||||
let channel = parts[3];
|
||||
let topic = parts[4..].join(" ");
|
||||
|
||||
let target = parts[2];
|
||||
let msg = parts[3..].join(" ");
|
||||
Self::TOPIC(channel.to_string(), (topic[1..]).to_string())
|
||||
}
|
||||
Some(&"333") => {
|
||||
let user = parts[4];
|
||||
let time = parts[5];
|
||||
|
||||
return Self::PRIVMSG(nick, target.to_string(), (msg[1..]).to_string());
|
||||
} else if parts.get(1) == Some(&"332") {
|
||||
let channel = parts[3];
|
||||
let topic = parts[4..].join(" ");
|
||||
Self::TOPIC_BY(user.to_string(), time.to_string())
|
||||
}
|
||||
Some(&"353") => {
|
||||
let channel = parts[4];
|
||||
let user = parts[5..].join(" ");
|
||||
|
||||
return Self::TOPIC(channel.to_string(), topic.to_string());
|
||||
} else if parts.get(1) == Some(&"333") {
|
||||
let user = parts[4];
|
||||
let time = parts[5];
|
||||
Self::NAMES(channel.to_string(), (user[1..]).to_string())
|
||||
}
|
||||
Some(&"PONG") => {
|
||||
let pong = parts[2];
|
||||
let server = parts[3];
|
||||
|
||||
return Self::TopicBy(user.to_string(), time.to_string());
|
||||
Self::PONG(pong.to_string(), (server[1..]).to_string())
|
||||
}
|
||||
_ => Self::OTHER(new.to_string()),
|
||||
}
|
||||
|
||||
Self::OTHER(new.to_string())
|
||||
}
|
||||
}
|
||||
|
|
34
src/lib.rs
34
src/lib.rs
|
@ -24,7 +24,7 @@
|
|||
//! is structured) see the [examples](https://git.karx.xyz/circe/async-circe/src/branch/master/examples) folder on our git.
|
||||
|
||||
#![warn(missing_docs)] // We want everything documented
|
||||
#![allow(clippy::needless_return)] // Wants to remove a return statement, but when it's removed the code doesn't compile
|
||||
#![allow(clippy::needless_return, non_camel_case_types)] // Wants to remove a return statement, but when it's removed the code doesn't compile
|
||||
#![feature(doc_cfg)]
|
||||
|
||||
use tokio::io::BufReader;
|
||||
|
@ -216,15 +216,14 @@ impl Client {
|
|||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn read(&mut self) -> Result<Option<commands::Command>, tokio::io::Error> {
|
||||
if let Some(string) = self.read_string().await? {
|
||||
let command = commands::Command::command_from_str(&string).await;
|
||||
let command = commands::Command::command_from_str(string).await;
|
||||
|
||||
if let commands::Command::PING(command) = command {
|
||||
if let Err(_e) = self.pong(&command).await {
|
||||
return Ok(None);
|
||||
}
|
||||
return Ok(Some(commands::Command::PONG("".to_string())));
|
||||
return Ok(Some(commands::Command::PING("".to_string())));
|
||||
}
|
||||
|
||||
return Ok(Some(command));
|
||||
}
|
||||
|
||||
|
@ -474,7 +473,7 @@ impl Client {
|
|||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn privmsg(&mut self, channel: &str, message: &str) -> Result<(), Error> {
|
||||
self.write(format!("PRIVMSG {} {}\r\n", channel, message))
|
||||
self.write(format!("PRIVMSG {} :{}\r\n", channel, message))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -527,34 +526,15 @@ impl Client {
|
|||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn topic(
|
||||
&mut self,
|
||||
channel: &str,
|
||||
topic: Option<&str>,
|
||||
) -> Result<(String, String, String, String), Error> {
|
||||
pub async fn topic(&mut self, channel: &str, topic: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(topic) = topic {
|
||||
self.write(format!("TOPIC {} :{}\r\n", channel, topic))
|
||||
.await?;
|
||||
return Ok((String::new(), String::new(), String::new(), String::new()));
|
||||
} else {
|
||||
// Can we make this more efficient? Yes! But how?
|
||||
self.write(format!("TOPIC {}\r\n", channel)).await?;
|
||||
let mut channel_channel = String::new();
|
||||
let mut channel_topic = String::new();
|
||||
if let Some(command) = self.read().await? {
|
||||
if let commands::Command::TOPIC(channel, topic) = command {
|
||||
channel_channel = channel;
|
||||
channel_topic = topic;
|
||||
}
|
||||
}
|
||||
let mut topic_return = (String::new(), String::new(), String::new(), String::new());
|
||||
if let Some(command) = self.read().await? {
|
||||
if let commands::Command::TopicBy(user, time) = command {
|
||||
topic_return = (channel_channel, channel_topic, user, time);
|
||||
}
|
||||
}
|
||||
return Ok(topic_return);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
Loading…
Reference in a new issue