Merge pull request #235 from simnalamburt/clippy

Fix all `cargo clippy` warnings.
This commit is contained in:
Aaron Weiss 2023-06-05 15:28:33 -04:00 committed by GitHub
commit 8eef9c5688
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 201 additions and 225 deletions

View file

@ -27,23 +27,20 @@ async fn main() -> irc::error::Result<()> {
let mut stream = client.stream()?; let mut stream = client.stream()?;
while let Some(message) = stream.next().await.transpose()? { while let Some(message) = stream.next().await.transpose()? {
match message.command { if let Command::Response(Response::RPL_ISUPPORT, _) = message.command {
Command::Response(Response::RPL_ISUPPORT, _) => { client.send_privmsg(
client.send_privmsg( "#commits",
"#commits", format!(
format!( "[{}/{}] ({}) {} [{}]",
"[{}/{}] ({}) {} [{}]", repository_slug,
repository_slug, branch,
branch, &commit[..7],
&commit[..7], commit_message,
commit_message, features,
features, ),
), )?;
)?;
client.send_quit("QUIT")?; client.send_quit("QUIT")?;
}
_ => (),
} }
} }

View file

@ -45,13 +45,10 @@ async fn main() -> irc::error::Result<()> {
fn process_msg(sender: &Sender, message: Message) -> error::Result<()> { fn process_msg(sender: &Sender, message: Message) -> error::Result<()> {
print!("{}", message); print!("{}", message);
match message.command { if let Command::PRIVMSG(ref target, ref msg) = message.command {
Command::PRIVMSG(ref target, ref msg) => { if msg.contains("pickles") {
if msg.contains("pickles") { sender.send_privmsg(target, "Hi!")?;
sender.send_privmsg(target, "Hi!")?;
}
} }
_ => (),
} }
Ok(()) Ok(())

View file

@ -22,7 +22,7 @@ async fn main() -> irc::error::Result<()> {
let message = stream.select_next_some().await?; let message = stream.select_next_some().await?;
if let Command::PRIVMSG(ref target, ref msg) = message.command { if let Command::PRIVMSG(ref target, ref msg) = message.command {
if msg.starts_with(&*client.current_nickname()) { if msg.starts_with(client.current_nickname()) {
let tokens: Vec<_> = msg.split(' ').collect(); let tokens: Vec<_> = msg.split(' ').collect();
if tokens.len() > 2 { if tokens.len() > 2 {
let n = tokens[0].len() + tokens[1].len() + 2; let n = tokens[0].len() + tokens[1].len() + 2;

View file

@ -19,13 +19,10 @@ async fn main() -> irc::error::Result<()> {
while let Some(message) = stream.next().await.transpose()? { while let Some(message) = stream.next().await.transpose()? {
print!("{}", message); print!("{}", message);
match message.command { if let Command::PRIVMSG(ref target, ref msg) = message.command {
Command::PRIVMSG(ref target, ref msg) => { if msg.contains(client.current_nickname()) {
if msg.contains(client.current_nickname()) { sender.send_privmsg(target, "Hi!")?;
sender.send_privmsg(target, "Hi!")?;
}
} }
_ => (),
} }
} }

View file

@ -20,13 +20,10 @@ async fn main() -> irc::error::Result<()> {
while let Some(message) = stream.next().await.transpose()? { while let Some(message) = stream.next().await.transpose()? {
print!("{}", message); print!("{}", message);
match message.command { if let Command::PRIVMSG(ref target, ref msg) = message.command {
Command::PRIVMSG(ref target, ref msg) => { if msg.contains(client.current_nickname()) {
if msg.contains(client.current_nickname()) { sender.send_privmsg(target, "Hi!")?;
sender.send_privmsg(target, "Hi!")?;
}
} }
_ => (),
} }
} }

View file

@ -22,13 +22,10 @@ async fn main() -> irc::error::Result<()> {
while let Some(message) = stream.next().await.transpose()? { while let Some(message) = stream.next().await.transpose()? {
print!("{}", message); print!("{}", message);
match message.command { if let Command::PRIVMSG(ref target, ref msg) = message.command {
Command::PRIVMSG(ref target, ref msg) => { if msg.contains(client.current_nickname()) {
if msg.contains(client.current_nickname()) { sender.send_privmsg(target, "Hi!")?;
sender.send_privmsg(target, "Hi!")?;
}
} }
_ => (),
} }
} }

View file

@ -65,11 +65,11 @@ impl Parser {
false false
} }
Text => !FORMAT_CHARACTERS.contains(&cur), Text => !FORMAT_CHARACTERS.contains(&cur),
ColorCode if cur.is_digit(10) => { ColorCode if cur.is_ascii_digit() => {
self.state = Foreground1(cur); self.state = Foreground1(cur);
false false
} }
Foreground1('0') if cur.is_digit(10) => { Foreground1('0') if cur.is_ascii_digit() => {
// can consume another digit if previous char was 0. // can consume another digit if previous char was 0.
self.state = Foreground2; self.state = Foreground2;
false false
@ -91,7 +91,7 @@ impl Parser {
self.state = Comma; self.state = Comma;
false false
} }
Comma if (cur.is_digit(10)) => { Comma if (cur.is_ascii_digit()) => {
self.state = Background1(cur); self.state = Background1(cur);
false false
} }

View file

@ -231,13 +231,13 @@ impl<'a> From<&'a Command> for String {
"MODE {}{}", "MODE {}{}",
u, u,
m.iter().fold(String::new(), |mut acc, mode| { m.iter().fold(String::new(), |mut acc, mode| {
acc.push_str(" "); acc.push(' ');
acc.push_str(&mode.to_string()); acc.push_str(&mode.to_string());
acc acc
}) })
), ),
Command::SERVICE(ref n, ref r, ref d, ref t, ref re, ref i) => { Command::SERVICE(ref nick, ref r0, ref dist, ref typ, ref r1, ref info) => {
stringify("SERVICE", &[n, r, d, t, re, i]) stringify("SERVICE", &[nick, r0, dist, typ, r1, info])
} }
Command::QUIT(Some(ref m)) => stringify("QUIT", &[m]), Command::QUIT(Some(ref m)) => stringify("QUIT", &[m]),
Command::QUIT(None) => stringify("QUIT", &[]), Command::QUIT(None) => stringify("QUIT", &[]),
@ -252,7 +252,7 @@ impl<'a> From<&'a Command> for String {
"MODE {}{}", "MODE {}{}",
u, u,
m.iter().fold(String::new(), |mut acc, mode| { m.iter().fold(String::new(), |mut acc, mode| {
acc.push_str(" "); acc.push(' ');
acc.push_str(&mode.to_string()); acc.push_str(&mode.to_string());
acc acc
}) })
@ -445,12 +445,10 @@ impl Command {
} else if cmd.eq_ignore_ascii_case("MODE") { } else if cmd.eq_ignore_ascii_case("MODE") {
if args.is_empty() { if args.is_empty() {
raw(cmd, args) raw(cmd, args)
} else if args[0].is_channel_name() {
Command::ChannelMODE(args[0].to_owned(), Mode::as_channel_modes(&args[1..])?)
} else { } else {
if args[0].is_channel_name() { Command::UserMODE(args[0].to_owned(), Mode::as_user_modes(&args[1..])?)
Command::ChannelMODE(args[0].to_owned(), Mode::as_channel_modes(&args[1..])?)
} else {
Command::UserMODE(args[0].to_owned(), Mode::as_user_modes(&args[1..])?)
}
} }
} else if cmd.eq_ignore_ascii_case("SERVICE") { } else if cmd.eq_ignore_ascii_case("SERVICE") {
if args.len() != 6 { if args.len() != 6 {
@ -665,7 +663,7 @@ impl Command {
} else if args.len() == 1 { } else if args.len() == 1 {
Command::WHO(Some(args[0].to_owned()), None) Command::WHO(Some(args[0].to_owned()), None)
} else if args.len() == 2 { } else if args.len() == 2 {
Command::WHO(Some(args[0].to_owned()), Some(&args[1][..] == "o")) Command::WHO(Some(args[0].to_owned()), Some(args[1] == "o"))
} else { } else {
raw(cmd, args) raw(cmd, args)
} }
@ -907,13 +905,12 @@ impl Command {
raw(cmd, args) raw(cmd, args)
} }
} else if cmd.eq_ignore_ascii_case("METADATA") { } else if cmd.eq_ignore_ascii_case("METADATA") {
if args.len() == 2 { match args.len() {
match args[1].parse() { 2 => match args[1].parse() {
Ok(c) => Command::METADATA(args[0].to_owned(), Some(c), None), Ok(c) => Command::METADATA(args[0].to_owned(), Some(c), None),
Err(_) => raw(cmd, args), Err(_) => raw(cmd, args),
} },
} else if args.len() > 2 { 3.. => match args[1].parse() {
match args[1].parse() {
Ok(c) => Command::METADATA( Ok(c) => Command::METADATA(
args[0].to_owned(), args[0].to_owned(),
Some(c), Some(c),
@ -930,9 +927,8 @@ impl Command {
raw(cmd, args) raw(cmd, args)
} }
} }
} },
} else { _ => raw(cmd, args),
raw(cmd, args)
} }
} else if cmd.eq_ignore_ascii_case("MONITOR") { } else if cmd.eq_ignore_ascii_case("MONITOR") {
if args.len() == 2 { if args.len() == 2 {

View file

@ -58,7 +58,7 @@ impl Message {
args: Vec<&str>, args: Vec<&str>,
) -> Result<Message, error::MessageParseError> { ) -> Result<Message, error::MessageParseError> {
Ok(Message { Ok(Message {
tags: tags, tags,
prefix: prefix.map(|p| p.into()), prefix: prefix.map(|p| p.into()),
command: Command::new(command, args)?, command: Command::new(command, args)?,
}) })
@ -112,43 +112,6 @@ impl Message {
_ => self.source_nickname(), _ => self.source_nickname(),
} }
} }
/// Converts a Message into a String according to the IRC protocol.
///
/// # Example
/// ```
/// # extern crate irc_proto;
/// # use irc_proto::Message;
/// # fn main() {
/// let msg = Message::new(
/// Some("ada"), "PRIVMSG", vec!["#channel", "Hi, everyone!"]
/// ).unwrap();
/// assert_eq!(msg.to_string(), ":ada PRIVMSG #channel :Hi, everyone!\r\n");
/// # }
/// ```
pub fn to_string(&self) -> String {
let mut ret = String::new();
if let Some(ref tags) = self.tags {
ret.push('@');
for tag in tags {
ret.push_str(&tag.0);
if let Some(ref value) = tag.1 {
ret.push('=');
escape_tag_value(&mut ret, &value);
}
ret.push(';');
}
ret.pop();
ret.push(' ');
}
if let Some(ref prefix) = self.prefix {
write!(ret, ":{} ", prefix).unwrap();
}
let cmd: String = From::from(&self.command);
ret.push_str(&cmd);
ret.push_str("\r\n");
ret
}
} }
impl From<Command> for Message { impl From<Command> for Message {
@ -261,8 +224,38 @@ impl<'a> From<&'a str> for Message {
} }
impl Display for Message { impl Display for Message {
/// Converts a Message into a String according to the IRC protocol.
///
/// # Example
/// ```
/// # extern crate irc_proto;
/// # use irc_proto::Message;
/// # fn main() {
/// let msg = Message::new(
/// Some("ada"), "PRIVMSG", vec!["#channel", "Hi, everyone!"]
/// ).unwrap();
/// assert_eq!(msg.to_string(), ":ada PRIVMSG #channel :Hi, everyone!\r\n");
/// # }
/// ```
fn fmt(&self, f: &mut Formatter) -> FmtResult { fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}", self.to_string()) if let Some(ref tags) = self.tags {
f.write_char('@')?;
for (i, tag) in tags.iter().enumerate() {
if i > 0 {
f.write_char(';')?;
}
f.write_str(&tag.0)?;
if let Some(ref value) = tag.1 {
f.write_char('=')?;
escape_tag_value(f, value)?;
}
}
f.write_char(' ')?;
}
if let Some(ref prefix) = self.prefix {
write!(f, ":{} ", prefix)?
}
write!(f, "{}\r\n", String::from(&self.command))
} }
} }
@ -273,36 +266,38 @@ impl Display for Message {
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Tag(pub String, pub Option<String>); pub struct Tag(pub String, pub Option<String>);
fn escape_tag_value(msg: &mut String, value: &str) { fn escape_tag_value(f: &mut dyn Write, value: &str) -> FmtResult {
for c in value.chars() { for c in value.chars() {
match c { match c {
';' => msg.push_str("\\:"), ';' => f.write_str("\\:")?,
' ' => msg.push_str("\\s"), ' ' => f.write_str("\\s")?,
'\\' => msg.push_str("\\\\"), '\\' => f.write_str("\\\\")?,
'\r' => msg.push_str("\\r"), '\r' => f.write_str("\\r")?,
'\n' => msg.push_str("\\n"), '\n' => f.write_str("\\n")?,
c => msg.push(c), c => f.write_char(c)?,
} }
} }
Ok(())
} }
fn unescape_tag_value(value: &str) -> String { fn unescape_tag_value(value: &str) -> String {
let mut unescaped = String::with_capacity(value.len()); let mut unescaped = String::with_capacity(value.len());
let mut iter = value.chars(); let mut iter = value.chars();
while let Some(c) = iter.next() { while let Some(c) = iter.next() {
if c == '\\' { let r = if c == '\\' {
match iter.next() { match iter.next() {
Some(':') => unescaped.push(';'), Some(':') => ';',
Some('s') => unescaped.push(' '), Some('s') => ' ',
Some('\\') => unescaped.push('\\'), Some('\\') => '\\',
Some('r') => unescaped.push('\r'), Some('r') => '\r',
Some('n') => unescaped.push('\n'), Some('n') => '\n',
Some(c) => unescaped.push(c), Some(c) => c,
None => break, None => break,
} }
} else { } else {
unescaped.push(c); c
} };
unescaped.push(r);
} }
unescaped unescaped
} }

View file

@ -139,11 +139,18 @@ impl ModeType for ChannelMode {
fn takes_arg(&self) -> bool { fn takes_arg(&self) -> bool {
use self::ChannelMode::*; use self::ChannelMode::*;
match *self { matches!(
Ban | Exception | Limit | InviteException | Key | Founder | Admin | Oper | Halfop *self,
| Voice => true, Ban | Exception
_ => false, | Limit
} | InviteException
| Key
| Founder
| Admin
| Oper
| Halfop
| Voice
)
} }
fn from_char(c: char) -> ChannelMode { fn from_char(c: char) -> ChannelMode {
@ -234,10 +241,10 @@ where
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
Mode::Plus(ref mode, Some(ref arg)) => write!(f, "{}{} {}", "+", mode, arg), Mode::Plus(ref mode, Some(ref arg)) => write!(f, "+{} {}", mode, arg),
Mode::Minus(ref mode, Some(ref arg)) => write!(f, "{}{} {}", "-", mode, arg), Mode::Minus(ref mode, Some(ref arg)) => write!(f, "-{} {}", mode, arg),
Mode::Plus(ref mode, None) => write!(f, "{}{}", "+", mode), Mode::Plus(ref mode, None) => write!(f, "+{}", mode),
Mode::Minus(ref mode, None) => write!(f, "{}{}", "-", mode), Mode::Minus(ref mode, None) => write!(f, "-{}", mode),
} }
} }
} }
@ -282,7 +289,7 @@ where
Some('-') => Minus, Some('-') => Minus,
Some(c) => { Some(c) => {
return Err(InvalidModeString { return Err(InvalidModeString {
string: pieces.join(" ").to_owned(), string: pieces.join(" "),
cause: InvalidModeModifier { modifier: c }, cause: InvalidModeModifier { modifier: c },
}) })
} }
@ -313,12 +320,11 @@ where
} }
// TODO: if there are extra args left, this should error // TODO: if there are extra args left, this should error
Ok(res)
} else { } else {
// No modifier // No modifier
Ok(res) };
}
Ok(res)
} }
#[cfg(test)] #[cfg(test)]

View file

@ -156,7 +156,7 @@ impl Connection {
let stream = Self::new_stream(config).await?; let stream = Self::new_stream(config).await?;
let framed = Framed::new(stream, IrcCodec::new(config.encoding())?); let framed = Framed::new(stream, IrcCodec::new(config.encoding())?);
Ok(Transport::new(&config, framed, tx)) Ok(Transport::new(config, framed, tx))
} }
#[cfg(all(feature = "tls-native", not(feature = "tls-rust")))] #[cfg(all(feature = "tls-native", not(feature = "tls-rust")))]
@ -188,7 +188,7 @@ impl Connection {
let mut client_cert_data = vec![]; let mut client_cert_data = vec![];
file.read_to_end(&mut client_cert_data)?; file.read_to_end(&mut client_cert_data)?;
let client_cert_pass = config.client_cert_pass(); let client_cert_pass = config.client_cert_pass();
let pkcs12_archive = Identity::from_pkcs12(&client_cert_data, &client_cert_pass)?; let pkcs12_archive = Identity::from_pkcs12(&client_cert_data, client_cert_pass)?;
builder.identity(pkcs12_archive); builder.identity(pkcs12_archive);
log::info!( log::info!(
"Using {} for client certificate authentication.", "Using {} for client certificate authentication.",
@ -215,7 +215,7 @@ impl Connection {
let stream = connector.connect(domain, stream).await?; let stream = connector.connect(domain, stream).await?;
let framed = Framed::new(stream, IrcCodec::new(config.encoding())?); let framed = Framed::new(stream, IrcCodec::new(config.encoding())?);
Ok(Transport::new(&config, framed, tx)) Ok(Transport::new(config, framed, tx))
} }
#[cfg(feature = "tls-rust")] #[cfg(feature = "tls-rust")]
@ -337,7 +337,7 @@ impl Connection {
let stream = connector.connect(domain, stream).await?; let stream = connector.connect(domain, stream).await?;
let framed = Framed::new(stream, IrcCodec::new(config.encoding())?); let framed = Framed::new(stream, IrcCodec::new(config.encoding())?);
Ok(Transport::new(&config, framed, tx)) Ok(Transport::new(config, framed, tx))
} }
async fn new_mocked_transport( async fn new_mocked_transport(
@ -363,7 +363,7 @@ impl Connection {
let stream = MockStream::new(&initial); let stream = MockStream::new(&initial);
let framed = Framed::new(stream, IrcCodec::new(config.encoding())?); let framed = Framed::new(stream, IrcCodec::new(config.encoding())?);
Ok(Transport::new(&config, framed, tx)) Ok(Transport::new(config, framed, tx))
} }
/// Gets a view of the internal logging if and only if this connection is using a mock stream. /// Gets a view of the internal logging if and only if this connection is using a mock stream.

View file

@ -394,18 +394,15 @@ impl Config {
/// Determines whether or not the nickname provided is the owner of the bot. /// Determines whether or not the nickname provided is the owner of the bot.
pub fn is_owner(&self, nickname: &str) -> bool { pub fn is_owner(&self, nickname: &str) -> bool {
self.owners.iter().find(|n| *n == nickname).is_some() self.owners.iter().any(|n| n == nickname)
} }
/// Gets the nickname specified in the configuration. /// Gets the nickname specified in the configuration.
pub fn nickname(&self) -> Result<&str> { pub fn nickname(&self) -> Result<&str> {
self.nickname self.nickname.as_deref().ok_or_else(|| InvalidConfig {
.as_ref() path: self.path(),
.map(String::as_str) cause: ConfigError::NicknameNotSpecified,
.ok_or_else(|| InvalidConfig { })
path: self.path(),
cause: ConfigError::NicknameNotSpecified,
})
} }
/// Gets the bot's nickserv password specified in the configuration. /// Gets the bot's nickserv password specified in the configuration.
@ -425,7 +422,7 @@ impl Config {
pub fn username(&self) -> &str { pub fn username(&self) -> &str {
self.username self.username
.as_ref() .as_ref()
.map_or(self.nickname().unwrap_or("user"), |s| &s) .map_or(self.nickname().unwrap_or("user"), |s| s)
} }
/// Gets the real name specified in the configuration. /// Gets the real name specified in the configuration.
@ -433,18 +430,15 @@ impl Config {
pub fn real_name(&self) -> &str { pub fn real_name(&self) -> &str {
self.realname self.realname
.as_ref() .as_ref()
.map_or(self.nickname().unwrap_or("irc"), |s| &s) .map_or(self.nickname().unwrap_or("irc"), |s| s)
} }
/// Gets the address of the server specified in the configuration. /// Gets the address of the server specified in the configuration.
pub fn server(&self) -> Result<&str> { pub fn server(&self) -> Result<&str> {
self.server self.server.as_deref().ok_or_else(|| InvalidConfig {
.as_ref() path: self.path(),
.map(String::as_str) cause: ConfigError::ServerNotSpecified,
.ok_or_else(|| InvalidConfig { })
path: self.path(),
cause: ConfigError::ServerNotSpecified,
})
} }
/// Gets the port of the server specified in the configuration. /// Gets the port of the server specified in the configuration.
@ -517,7 +511,7 @@ impl Config {
/// Gets the path to the TLS certificate in DER format if specified. /// Gets the path to the TLS certificate in DER format if specified.
#[cfg(any(feature = "tls-native", feature = "tls-rust"))] #[cfg(any(feature = "tls-native", feature = "tls-rust"))]
pub fn cert_path(&self) -> Option<&str> { pub fn cert_path(&self) -> Option<&str> {
self.cert_path.as_ref().map(String::as_str) self.cert_path.as_deref()
} }
/// Gets whether or not to dangerously accept invalid certificates. /// Gets whether or not to dangerously accept invalid certificates.
@ -532,7 +526,7 @@ impl Config {
/// Gets the path to the client authentication certificate in DER format if specified. /// Gets the path to the client authentication certificate in DER format if specified.
#[cfg(any(feature = "tls-native", feature = "tls-rust"))] #[cfg(any(feature = "tls-native", feature = "tls-rust"))]
pub fn client_cert_path(&self) -> Option<&str> { pub fn client_cert_path(&self) -> Option<&str> {
self.client_cert_path.as_ref().map(String::as_str) self.client_cert_path.as_deref()
} }
/// Gets the password to the client authentication certificate. /// Gets the password to the client authentication certificate.
@ -544,7 +538,7 @@ impl Config {
/// Gets the encoding to use for this connection. This requires the encode feature to work. /// Gets the encoding to use for this connection. This requires the encode feature to work.
/// This defaults to UTF-8 when not specified. /// This defaults to UTF-8 when not specified.
pub fn encoding(&self) -> &str { pub fn encoding(&self) -> &str {
self.encoding.as_ref().map_or("UTF-8", |s| &s) self.encoding.as_ref().map_or("UTF-8", |s| s)
} }
/// Gets the channels to join upon connection. /// Gets the channels to join upon connection.
@ -574,7 +568,7 @@ impl Config {
/// This defaults to `irc:version:env` when not specified. /// This defaults to `irc:version:env` when not specified.
/// For example, `irc:0.12.0:Compiled with rustc` /// For example, `irc:0.12.0:Compiled with rustc`
pub fn version(&self) -> &str { pub fn version(&self) -> &str {
self.version.as_ref().map_or(crate::VERSION_STR, |s| &s) self.version.as_ref().map_or(crate::VERSION_STR, |s| s)
} }
/// Gets the string to be sent in response to CTCP SOURCE requests. /// Gets the string to be sent in response to CTCP SOURCE requests.
@ -624,7 +618,7 @@ impl Config {
/// Gets the NickServ command sequence to recover a nickname. /// Gets the NickServ command sequence to recover a nickname.
/// This defaults to `["GHOST"]` when not specified. /// This defaults to `["GHOST"]` when not specified.
pub fn ghost_sequence(&self) -> Option<&[String]> { pub fn ghost_sequence(&self) -> Option<&[String]> {
self.ghost_sequence.as_ref().map(Vec::as_slice) self.ghost_sequence.as_deref()
} }
/// Looks up the specified string in the options map. /// Looks up the specified string in the options map.
@ -642,7 +636,7 @@ impl Config {
/// This defaults to false when not specified. /// This defaults to false when not specified.
/// This has no effect if `use_mock_connection` is not `true`. /// This has no effect if `use_mock_connection` is not `true`.
pub fn mock_initial_value(&self) -> &str { pub fn mock_initial_value(&self) -> &str {
self.mock_initial_value.as_ref().map_or("", |s| &s) self.mock_initial_value.as_ref().map_or("", |s| s)
} }
} }
@ -661,16 +655,16 @@ mod test {
#[allow(unused)] #[allow(unused)]
fn test_config() -> Config { fn test_config() -> Config {
Config { Config {
owners: vec![format!("test")], owners: vec!["test".to_string()],
nickname: Some(format!("test")), nickname: Some("test".to_string()),
username: Some(format!("test")), username: Some("test".to_string()),
realname: Some(format!("test")), realname: Some("test".to_string()),
password: Some(String::new()), password: Some(String::new()),
umodes: Some(format!("+BR")), umodes: Some("+BR".to_string()),
server: Some(format!("irc.test.net")), server: Some("irc.test.net".to_string()),
port: Some(6667), port: Some(6667),
encoding: Some(format!("UTF-8")), encoding: Some("UTF-8".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
..Default::default() ..Default::default()
} }
@ -679,7 +673,7 @@ mod test {
#[test] #[test]
fn is_owner() { fn is_owner() {
let cfg = Config { let cfg = Config {
owners: vec![format!("test"), format!("test2")], owners: vec!["test".to_string(), "test2".to_string()],
..Default::default() ..Default::default()
}; };
assert!(cfg.is_owner("test")); assert!(cfg.is_owner("test"));
@ -692,7 +686,7 @@ mod test {
let cfg = Config { let cfg = Config {
options: { options: {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert(format!("testing"), format!("test")); map.insert("testing".to_string(), "test".to_string());
map map
}, },
..Default::default() ..Default::default()

View file

@ -31,9 +31,9 @@ impl User {
let username = state.find('@').map(|i| state[..i].to_owned()); let username = state.find('@').map(|i| state[..i].to_owned());
let hostname = state.find('@').map(|i| state[i + 1..].to_owned()); let hostname = state.find('@').map(|i| state[i + 1..].to_owned());
User { User {
nickname: nickname, nickname,
username: username, username,
hostname: hostname, hostname,
access_levels: { access_levels: {
let mut ranks = ranks.clone(); let mut ranks = ranks.clone();
ranks.push(AccessLevel::Member); ranks.push(AccessLevel::Member);
@ -248,7 +248,7 @@ mod test {
fn create_user() { fn create_user() {
let user = User::new("~owner"); let user = User::new("~owner");
let exp = User { let exp = User {
nickname: format!("owner"), nickname: "owner".to_string(),
username: None, username: None,
hostname: None, hostname: None,
highest_access_level: Owner, highest_access_level: Owner,
@ -263,7 +263,7 @@ mod test {
fn create_user_complex() { fn create_user_complex() {
let user = User::new("~&+user"); let user = User::new("~&+user");
let exp = User { let exp = User {
nickname: format!("user"), nickname: "user".to_string(),
username: None, username: None,
hostname: None, hostname: None,
highest_access_level: Owner, highest_access_level: Owner,

View file

@ -113,11 +113,7 @@ macro_rules! pub_state_base {
} }
/// Joins the specified channel or chanlist using the specified key or keylist. /// Joins the specified channel or chanlist using the specified key or keylist.
pub fn send_join_with_keys<S1, S2>( pub fn send_join_with_keys<S1, S2>(&self, chanlist: S1, keylist: S2) -> error::Result<()>
&self,
chanlist: &str,
keylist: &str,
) -> error::Result<()>
where where
S1: fmt::Display, S1: fmt::Display,
S2: fmt::Display, S2: fmt::Display,
@ -487,7 +483,7 @@ impl Stream for ClientStream {
match ready!(Pin::new(&mut self.as_mut().stream).poll_next(cx)) { match ready!(Pin::new(&mut self.as_mut().stream).poll_next(cx)) {
Some(Ok(msg)) => { Some(Ok(msg)) => {
self.state.handle_message(&msg)?; self.state.handle_message(&msg)?;
return Poll::Ready(Some(Ok(msg))); Poll::Ready(Some(Ok(msg)))
} }
other => Poll::Ready(other), other => Poll::Ready(other),
} }
@ -526,7 +522,7 @@ impl ClientState {
fn send<M: Into<Message>>(&self, msg: M) -> error::Result<()> { fn send<M: Into<Message>>(&self, msg: M) -> error::Result<()> {
let msg = msg.into(); let msg = msg.into();
self.handle_sent_message(&msg)?; self.handle_sent_message(&msg)?;
Ok(self.sender.send(msg)?) self.sender.send(msg)
} }
/// Gets the current nickname in use. /// Gets the current nickname in use.
@ -547,11 +543,8 @@ impl ClientState {
fn handle_sent_message(&self, msg: &Message) -> error::Result<()> { fn handle_sent_message(&self, msg: &Message) -> error::Result<()> {
log::trace!("[SENT] {}", msg.to_string()); log::trace!("[SENT] {}", msg.to_string());
match msg.command { if let PART(ref chan, _) = msg.command {
PART(ref chan, _) => { let _ = self.chanlists.write().remove(chan);
let _ = self.chanlists.write().remove(chan);
}
_ => (),
} }
Ok(()) Ok(())
@ -602,7 +595,7 @@ impl ClientState {
let joined_chans = self.chanlists.read(); let joined_chans = self.chanlists.read();
for chan in joined_chans for chan in joined_chans
.keys() .keys()
.filter(|x| config_chans.iter().find(|c| c == x).is_none()) .filter(|x| !config_chans.iter().any(|c| c == *x))
{ {
self.send_join(chan)? self.send_join(chan)?
} }
@ -805,7 +798,7 @@ impl ClientState {
#[cfg(feature = "ctcp")] #[cfg(feature = "ctcp")]
fn send_ctcp_internal(&self, target: &str, msg: &str) -> error::Result<()> { fn send_ctcp_internal(&self, target: &str, msg: &str) -> error::Result<()> {
self.send_notice(target, &format!("\u{001}{}\u{001}", msg)) self.send_notice(target, format!("\u{001}{}\u{001}", msg))
} }
#[cfg(not(feature = "ctcp"))] #[cfg(not(feature = "ctcp"))]
@ -993,7 +986,7 @@ impl Client {
let stream = self let stream = self
.incoming .incoming
.take() .take()
.ok_or_else(|| error::Error::StreamAlreadyConfigured)?; .ok_or(error::Error::StreamAlreadyConfigured)?;
Ok(ClientStream { Ok(ClientStream {
state: Arc::clone(&self.state), state: Arc::clone(&self.state),
@ -1114,12 +1107,12 @@ mod test {
pub fn test_config() -> Config { pub fn test_config() -> Config {
Config { Config {
owners: vec![format!("test")], owners: vec!["test".to_string()],
nickname: Some(format!("test")), nickname: Some("test".to_string()),
alt_nicks: vec![format!("test2")], alt_nicks: vec!["test2".to_string()],
server: Some(format!("irc.test.net")), server: Some("irc.test.net".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
user_info: Some(format!("Testing.")), user_info: Some("Testing.".to_string()),
use_mock_connection: true, use_mock_connection: true,
..Default::default() ..Default::default()
} }
@ -1180,8 +1173,8 @@ mod test {
let value = ":irc.test.net 376 test :End of /MOTD command.\r\n"; let value = ":irc.test.net 376 test :End of /MOTD command.\r\n";
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
mock_initial_value: Some(value.to_owned()), mock_initial_value: Some(value.to_owned()),
nick_password: Some(format!("password")), nick_password: Some("password".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
..test_config() ..test_config()
}) })
.await?; .await?;
@ -1199,11 +1192,11 @@ mod test {
let value = ":irc.test.net 376 test :End of /MOTD command\r\n"; let value = ":irc.test.net 376 test :End of /MOTD command\r\n";
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
mock_initial_value: Some(value.to_owned()), mock_initial_value: Some(value.to_owned()),
nickname: Some(format!("test")), nickname: Some("test".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
channel_keys: { channel_keys: {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert(format!("#test2"), format!("password")); map.insert("#test2".to_string(), "password".to_string());
map map
}, },
..test_config() ..test_config()
@ -1223,10 +1216,10 @@ mod test {
:irc.test.net 376 test2 :End of /MOTD command.\r\n"; :irc.test.net 376 test2 :End of /MOTD command.\r\n";
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
mock_initial_value: Some(value.to_owned()), mock_initial_value: Some(value.to_owned()),
nickname: Some(format!("test")), nickname: Some("test".to_string()),
alt_nicks: vec![format!("test2")], alt_nicks: vec!["test2".to_string()],
nick_password: Some(format!("password")), nick_password: Some("password".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
should_ghost: true, should_ghost: true,
..test_config() ..test_config()
}) })
@ -1246,12 +1239,12 @@ mod test {
:irc.test.net 376 test2 :End of /MOTD command.\r\n"; :irc.test.net 376 test2 :End of /MOTD command.\r\n";
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
mock_initial_value: Some(value.to_owned()), mock_initial_value: Some(value.to_owned()),
nickname: Some(format!("test")), nickname: Some("test".to_string()),
alt_nicks: vec![format!("test2")], alt_nicks: vec!["test2".to_string()],
nick_password: Some(format!("password")), nick_password: Some("password".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
should_ghost: true, should_ghost: true,
ghost_sequence: Some(vec![format!("RECOVER"), format!("RELEASE")]), ghost_sequence: Some(vec!["RECOVER".to_string(), "RELEASE".to_string()]),
..test_config() ..test_config()
}) })
.await?; .await?;
@ -1270,9 +1263,9 @@ mod test {
let value = ":irc.test.net 376 test :End of /MOTD command.\r\n"; let value = ":irc.test.net 376 test :End of /MOTD command.\r\n";
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
mock_initial_value: Some(value.to_owned()), mock_initial_value: Some(value.to_owned()),
nickname: Some(format!("test")), nickname: Some("test".to_string()),
umodes: Some(format!("+B")), umodes: Some("+B".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
..test_config() ..test_config()
}) })
.await?; .await?;
@ -1308,7 +1301,6 @@ mod test {
.await?; .await?;
let res = client.stream()?.try_collect::<Vec<_>>().await; let res = client.stream()?.try_collect::<Vec<_>>().await;
if let Err(Error::NoUsableNick) = res { if let Err(Error::NoUsableNick) = res {
()
} else { } else {
panic!("expected error when no valid nicks were specified") panic!("expected error when no valid nicks were specified")
} }
@ -1319,7 +1311,7 @@ mod test {
async fn send() -> Result<()> { async fn send() -> Result<()> {
let mut client = Client::from_config(test_config()).await?; let mut client = Client::from_config(test_config()).await?;
assert!(client assert!(client
.send(PRIVMSG(format!("#test"), format!("Hi there!"))) .send(PRIVMSG("#test".to_string(), "Hi there!".to_string()))
.is_ok()); .is_ok());
client.stream()?.collect().await?; client.stream()?.collect().await?;
assert_eq!( assert_eq!(
@ -1333,7 +1325,10 @@ mod test {
async fn send_no_newline_injection() -> Result<()> { async fn send_no_newline_injection() -> Result<()> {
let mut client = Client::from_config(test_config()).await?; let mut client = Client::from_config(test_config()).await?;
assert!(client assert!(client
.send(PRIVMSG(format!("#test"), format!("Hi there!\r\nJOIN #bad"))) .send(PRIVMSG(
"#test".to_string(),
"Hi there!\r\nJOIN #bad".to_string()
))
.is_ok()); .is_ok());
client.stream()?.collect().await?; client.stream()?.collect().await?;
assert_eq!( assert_eq!(
@ -1391,7 +1386,7 @@ mod test {
assert_eq!(client.list_channels(), Some(vec!["#test".to_owned()])); assert_eq!(client.list_channels(), Some(vec!["#test".to_owned()]));
// we ignore the result, as soon as we queue an outgoing message we // we ignore the result, as soon as we queue an outgoing message we
// update client state, regardless if the queue is available or not. // update client state, regardless if the queue is available or not.
let _ = client.send(PART(format!("#test"), None)); let _ = client.send(PART("#test".to_string(), None));
assert_eq!(client.list_channels(), Some(vec![])); assert_eq!(client.list_channels(), Some(vec![]));
Ok(()) Ok(())
} }
@ -1520,8 +1515,8 @@ mod test {
let value = ":test!test@test PRIVMSG #test :\u{001}\r\n"; let value = ":test!test@test PRIVMSG #test :\u{001}\r\n";
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
mock_initial_value: Some(value.to_owned()), mock_initial_value: Some(value.to_owned()),
nickname: Some(format!("test")), nickname: Some("test".to_string()),
channels: vec![format!("#test"), format!("#test2")], channels: vec!["#test".to_string(), "#test2".to_string()],
..test_config() ..test_config()
}) })
.await?; .await?;
@ -1664,8 +1659,8 @@ mod test {
#[tokio::test] #[tokio::test]
async fn identify_with_password() -> Result<()> { async fn identify_with_password() -> Result<()> {
let mut client = Client::from_config(Config { let mut client = Client::from_config(Config {
nickname: Some(format!("test")), nickname: Some("test".to_string()),
password: Some(format!("password")), password: Some("password".to_string()),
..test_config() ..test_config()
}) })
.await?; .await?;

View file

@ -96,7 +96,7 @@ impl Pinger {
let mut this = self.project(); let mut this = self.project();
this.tx.send(Command::PING(data.clone(), None).into())?; this.tx.send(Command::PING(data, None).into())?;
if this.ping_deadline.is_none() { if this.ping_deadline.is_none() {
let ping_deadline = time::sleep(*this.ping_timeout); let ping_deadline = time::sleep(*this.ping_timeout);
@ -118,10 +118,15 @@ impl Future for Pinger {
} }
} }
if let Poll::Ready(_) = self.as_mut().project().ping_interval.poll_tick(cx) { if self
if *self.as_mut().project().enabled { .as_mut()
self.as_mut().send_ping()?; .project()
} .ping_interval
.poll_tick(cx)
.is_ready()
&& *self.as_mut().project().enabled
{
self.as_mut().send_ping()?;
} }
Poll::Pending Poll::Pending