diff --git a/Cargo.toml b/Cargo.toml index 15719d2..916e29d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,11 +27,11 @@ json = ["serde_json"] yaml = ["serde_yaml"] [dependencies] +thiserror = "1.0.2" bufstream = "0.1" bytes = "0.4" chrono = "0.4" encoding = "0.2" -failure = "0.1" irc-proto = { version = "*", path = "irc-proto" } log = "0.4" native-tls = "0.2" @@ -46,7 +46,7 @@ toml = { version = "0.4", optional = true } pin-utils = "0.1.0-alpha.4" parking_lot = "0.9.0" futures-channel = "0.3.1" -futures-util = "0.3.1" +futures-util = { version = "0.3.1", features = ["sink"] } [dev-dependencies] futures = "0.3.1" diff --git a/irc-proto/Cargo.toml b/irc-proto/Cargo.toml index 91463ca..0dbb3a6 100644 --- a/irc-proto/Cargo.toml +++ b/irc-proto/Cargo.toml @@ -8,6 +8,7 @@ keywords = ["irc", "protocol", "tokio"] categories = ["network-programming"] documentation = "https://docs.rs/irc-proto/" repository = "https://github.com/aatxe/irc" +edition = "2018" [badges] travis-ci = { repository = "aatxe/irc" } @@ -18,6 +19,6 @@ default = ["tokio", "tokio-util", "bytes"] [dependencies] bytes = { version = "0.5", optional = true } encoding = "0.2" -failure = "0.1" +thiserror = "1.0.2" tokio-util = { version = "0.2.0", optional = true } tokio = { version = "0.2.0", optional = true } diff --git a/irc-proto/src/colors.rs b/irc-proto/src/colors.rs index 239f7a0..ba9d5af 100644 --- a/irc-proto/src/colors.rs +++ b/irc-proto/src/colors.rs @@ -118,7 +118,7 @@ impl FormattedStringExt<'static> for String { #[cfg(test)] mod test { - use colors::FormattedStringExt; + use crate::colors::FormattedStringExt; use std::borrow::Cow; macro_rules! test_formatted_string_ext { diff --git a/irc-proto/src/command.rs b/irc-proto/src/command.rs index b6fcbaf..b0c4c8b 100644 --- a/irc-proto/src/command.rs +++ b/irc-proto/src/command.rs @@ -1,10 +1,10 @@ //! Enumeration of all available client commands. use std::str::FromStr; -use chan::ChannelExt; -use error::MessageParseError; -use mode::{ChannelMode, Mode, UserMode}; -use response::Response; +use crate::chan::ChannelExt; +use crate::error::MessageParseError; +use crate::mode::{ChannelMode, Mode, UserMode}; +use crate::response::Response; /// List of all client commands as defined in [RFC 2812](http://tools.ietf.org/html/rfc2812). This /// also includes commands from the diff --git a/irc-proto/src/error.rs b/irc-proto/src/error.rs index 0343888..43b24f7 100644 --- a/irc-proto/src/error.rs +++ b/irc-proto/src/error.rs @@ -1,57 +1,57 @@ //! IRC protocol errors using `failure`. -use std::io::Error as IoError; +use thiserror::Error; /// A `Result` type for IRC `ProtocolErrors`. -pub type Result = ::std::result::Result; +pub type Result = ::std::result::Result; /// An IRC protocol error. -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum ProtocolError { /// An internal I/O error. - #[fail(display = "an io error occurred")] - Io(#[cause] IoError), + #[error("an io error occurred")] + Io(#[source] std::io::Error), /// Error for invalid messages. - #[fail(display = "invalid message: {}", string)] + #[error("invalid message: {}", string)] InvalidMessage { /// The string that failed to parse. string: String, /// The detailed message parsing error. - #[cause] + #[source] cause: MessageParseError, }, } -impl From for ProtocolError { - fn from(e: IoError) -> ProtocolError { +impl From for ProtocolError { + fn from(e: std::io::Error) -> ProtocolError { ProtocolError::Io(e) } } /// Errors that occur when parsing messages. -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum MessageParseError { /// The message was empty. - #[fail(display = "empty message")] + #[error("empty message")] EmptyMessage, /// The command was invalid (i.e. missing). - #[fail(display = "invalid command")] + #[error("invalid command")] InvalidCommand, /// The mode string was malformed. - #[fail(display = "invalid mode string: {}", string)] + #[error("invalid mode string: {}", string)] InvalidModeString { /// The invalid mode string. string: String, /// The detailed mode parsing error. - #[cause] + #[source] cause: ModeParseError, }, /// The subcommand used was invalid. - #[fail(display = "invalid {} subcommand: {}", cmd, sub)] + #[error("invalid {} subcommand: {}", cmd, sub)] InvalidSubcommand { /// The command whose invalid subcommand was referenced. cmd: &'static str, @@ -61,16 +61,16 @@ pub enum MessageParseError { } /// Errors that occur while parsing mode strings. -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum ModeParseError { /// Invalid modifier used in a mode string (only + and - are valid). - #[fail(display = "invalid mode modifier: {}", modifier)] + #[error("invalid mode modifier: {}", modifier)] InvalidModeModifier { /// The invalid mode modifier. modifier: char, }, /// Missing modifier used in a mode string. - #[fail(display = "missing mode modifier")] + #[error("missing mode modifier")] MissingModeModifier, } diff --git a/irc-proto/src/irc.rs b/irc-proto/src/irc.rs index a11b556..33fa3dc 100644 --- a/irc-proto/src/irc.rs +++ b/irc-proto/src/irc.rs @@ -2,9 +2,9 @@ use bytes::BytesMut; use tokio_util::codec::{Decoder, Encoder}; -use error; -use line::LineCodec; -use message::Message; +use crate::error; +use crate::line::LineCodec; +use crate::message::Message; /// An IRC codec built around an inner codec. pub struct IrcCodec { diff --git a/irc-proto/src/lib.rs b/irc-proto/src/lib.rs index fe764f9..80cc1c4 100644 --- a/irc-proto/src/lib.rs +++ b/irc-proto/src/lib.rs @@ -2,16 +2,6 @@ #![warn(missing_docs)] -#[cfg(feature = "tokio")] -extern crate bytes; -extern crate encoding; -#[macro_use] -extern crate failure; -#[cfg(feature = "tokio")] -extern crate tokio; -#[cfg(feature = "tokio-util")] -extern crate tokio_util; - pub mod caps; pub mod chan; pub mod colors; diff --git a/irc-proto/src/line.rs b/irc-proto/src/line.rs index 3c75128..85283f9 100644 --- a/irc-proto/src/line.rs +++ b/irc-proto/src/line.rs @@ -7,7 +7,7 @@ use encoding::label::encoding_from_whatwg_label; use encoding::{DecoderTrap, EncoderTrap, EncodingRef}; use tokio_util::codec::{Decoder, Encoder}; -use error; +use crate::error; /// A line-based codec parameterized by an encoding. pub struct LineCodec { diff --git a/irc-proto/src/message.rs b/irc-proto/src/message.rs index e121ca8..8fbb544 100644 --- a/irc-proto/src/message.rs +++ b/irc-proto/src/message.rs @@ -3,11 +3,11 @@ use std::borrow::ToOwned; use std::fmt::{Display, Formatter, Result as FmtResult, Write}; use std::str::FromStr; -use chan::ChannelExt; -use command::Command; -use error; -use error::{MessageParseError, ProtocolError}; -use prefix::Prefix; +use crate::chan::ChannelExt; +use crate::command::Command; +use crate::error; +use crate::error::{MessageParseError, ProtocolError}; +use crate::prefix::Prefix; /// A data structure representing an IRC message according to the protocol specification. It /// consists of a collection of IRCv3 tags, a prefix (describing the source of the message), and @@ -276,7 +276,7 @@ pub struct Tag(pub String, pub Option); #[cfg(test)] mod test { use super::{Message, Tag}; - use command::Command::{Raw, PRIVMSG, QUIT}; + use crate::command::Command::{Raw, PRIVMSG, QUIT}; #[test] fn new() { diff --git a/irc-proto/src/mode.rs b/irc-proto/src/mode.rs index 4891776..03a0cf5 100644 --- a/irc-proto/src/mode.rs +++ b/irc-proto/src/mode.rs @@ -1,10 +1,10 @@ //! A module defining an API for IRC user and channel modes. use std::fmt; -use command::Command; -use error::MessageParseError; -use error::MessageParseError::InvalidModeString; -use error::ModeParseError::*; +use crate::command::Command; +use crate::error::MessageParseError; +use crate::error::MessageParseError::InvalidModeString; +use crate::error::ModeParseError::*; /// A marker trait for different kinds of Modes. pub trait ModeType: fmt::Display + fmt::Debug + Clone + PartialEq { diff --git a/src/client/data/config.rs b/src/client/data/config.rs index ba01b1c..a26c869 100644 --- a/src/client/data/config.rs +++ b/src/client/data/config.rs @@ -535,6 +535,7 @@ impl Config { #[cfg(test)] mod test { use super::Config; + use anyhow::Result; use std::collections::HashMap; #[allow(unused)] @@ -601,7 +602,7 @@ mod test { #[test] #[cfg(feature = "json")] - fn load_from_json() -> Result<(), failure::Error> { + fn load_from_json() -> Result<()> { const DATA: &str = include_str!("client_config.json"); assert_eq!( Config::load_json("client_config.json", DATA)?.with_path("client_config.json"), @@ -612,7 +613,7 @@ mod test { #[test] #[cfg(feature = "toml")] - fn load_from_toml() -> Result<(), failure::Error> { + fn load_from_toml() -> Result<()> { const DATA: &str = include_str!("client_config.toml"); assert_eq!( Config::load_toml("client_config.toml", DATA)?.with_path("client_config.toml"), @@ -623,7 +624,7 @@ mod test { #[test] #[cfg(feature = "yaml")] - fn load_from_yaml() -> Result<(), failure::Error> { + fn load_from_yaml() -> Result<()> { const DATA: &str = include_str!("client_config.yaml"); assert_eq!( Config::load_yaml("client_config.yaml", DATA)?.with_path("client_config.yaml"), diff --git a/src/client/mod.rs b/src/client/mod.rs index f945550..4475b57 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1086,6 +1086,7 @@ mod test { ChannelMode, IrcCodec, Mode, }, }; + use anyhow::Result; use futures::prelude::*; pub fn test_config() -> Config { @@ -1120,7 +1121,7 @@ mod test { } #[tokio::test] - async fn stream() -> Result<(), failure::Error> { + async fn stream() -> Result<()> { let exp = "PRIVMSG test :Hi!\r\nPRIVMSG test :This is a test!\r\n\ :test!test@test JOIN #test\r\n"; @@ -1136,7 +1137,7 @@ mod test { } #[tokio::test] - async fn handle_message() -> Result<(), failure::Error> { + async fn handle_message() -> Result<()> { let value = ":irc.test.net 376 test :End of /MOTD command.\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1152,7 +1153,7 @@ mod test { } #[tokio::test] - async fn handle_end_motd_with_nick_password() -> Result<(), failure::Error> { + async fn handle_end_motd_with_nick_password() -> Result<()> { let value = ":irc.test.net 376 test :End of /MOTD command.\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1171,7 +1172,7 @@ mod test { } #[tokio::test] - async fn handle_end_motd_with_chan_keys() -> Result<(), failure::Error> { + async fn handle_end_motd_with_chan_keys() -> Result<()> { let value = ":irc.test.net 376 test :End of /MOTD command\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1194,7 +1195,7 @@ mod test { } #[tokio::test] - async fn handle_end_motd_with_ghost() -> Result<(), failure::Error> { + async fn handle_end_motd_with_ghost() -> Result<()> { let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\ :irc.test.net 376 test2 :End of /MOTD command.\r\n"; let mut client = Client::from_config(Config { @@ -1217,7 +1218,7 @@ mod test { } #[tokio::test] - async fn handle_end_motd_with_ghost_seq() -> Result<(), failure::Error> { + async fn handle_end_motd_with_ghost_seq() -> Result<()> { let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\ :irc.test.net 376 test2 :End of /MOTD command.\r\n"; let mut client = Client::from_config(Config { @@ -1242,7 +1243,7 @@ mod test { } #[tokio::test] - async fn handle_end_motd_with_umodes() -> Result<(), failure::Error> { + async fn handle_end_motd_with_umodes() -> Result<()> { let value = ":irc.test.net 376 test :End of /MOTD command.\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1261,7 +1262,7 @@ mod test { } #[tokio::test] - async fn nickname_in_use() -> Result<(), failure::Error> { + async fn nickname_in_use() -> Result<()> { let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1274,7 +1275,7 @@ mod test { } #[tokio::test] - async fn ran_out_of_nicknames() -> Result<(), failure::Error> { + async fn ran_out_of_nicknames() -> Result<()> { let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\ :irc.pdgn.co 433 * test2 :Nickname is already in use.\r\n"; let mut client = Client::from_config(Config { @@ -1292,7 +1293,7 @@ mod test { } #[tokio::test] - async fn send() -> Result<(), failure::Error> { + async fn send() -> Result<()> { let mut client = Client::from_config(test_config()).await?; assert!(client .send(PRIVMSG(format!("#test"), format!("Hi there!"))) @@ -1306,7 +1307,7 @@ mod test { } #[tokio::test] - async fn send_no_newline_injection() -> Result<(), failure::Error> { + async fn send_no_newline_injection() -> Result<()> { let mut client = Client::from_config(test_config()).await?; assert!(client .send(PRIVMSG(format!("#test"), format!("Hi there!\r\nJOIN #bad"))) @@ -1320,7 +1321,7 @@ mod test { } #[tokio::test] - async fn send_raw_is_really_raw() -> Result<(), failure::Error> { + async fn send_raw_is_really_raw() -> Result<()> { let mut client = Client::from_config(test_config()).await?; assert!(client .send(Raw("PASS".to_owned(), vec!["password".to_owned()], None)) @@ -1338,7 +1339,7 @@ mod test { #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn channel_tracking_names() -> Result<(), failure::Error> { + async fn channel_tracking_names() -> Result<()> { let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1355,7 +1356,7 @@ mod test { /* #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn channel_tracking_names_part() -> Result<(), failure::Error> { + async fn channel_tracking_names_part() -> Result<()> { use crate::proto::command::Command::PART; let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n"; @@ -1373,7 +1374,7 @@ mod test { #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn user_tracking_names() -> Result<(), failure::Error> { + async fn user_tracking_names() -> Result<()> { let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1390,7 +1391,7 @@ mod test { #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn user_tracking_names_join() -> Result<(), failure::Error> { + async fn user_tracking_names_join() -> Result<()> { let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n\ :test2!test@test JOIN #test\r\n"; let mut client = Client::from_config(Config { @@ -1413,7 +1414,7 @@ mod test { #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn user_tracking_names_kick() -> Result<(), failure::Error> { + async fn user_tracking_names_kick() -> Result<()> { let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n\ :owner!test@test KICK #test test\r\n"; let mut client = Client::from_config(Config { @@ -1431,7 +1432,7 @@ mod test { #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn user_tracking_names_part() -> Result<(), failure::Error> { + async fn user_tracking_names_part() -> Result<()> { let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n\ :owner!test@test PART #test\r\n"; let mut client = Client::from_config(Config { @@ -1449,7 +1450,7 @@ mod test { #[tokio::test] #[cfg(not(feature = "nochanlists"))] - async fn user_tracking_names_mode() -> Result<(), failure::Error> { + async fn user_tracking_names_mode() -> Result<()> { let value = ":irc.test.net 353 test = #test :+test ~owner &admin\r\n\ :test!test@test MODE #test +o test\r\n"; let mut client = Client::from_config(Config { @@ -1478,7 +1479,7 @@ mod test { #[tokio::test] #[cfg(feature = "nochanlists")] - async fn no_user_tracking() -> Result<(), failure::Error> { + async fn no_user_tracking() -> Result<()> { let value = ":irc.test.net 353 test = #test :test ~owner &admin"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1491,7 +1492,7 @@ mod test { } #[tokio::test] - async fn handle_single_soh() -> Result<(), failure::Error> { + async fn handle_single_soh() -> Result<()> { let value = ":test!test@test PRIVMSG #test :\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1506,7 +1507,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn finger_response() -> Result<(), failure::Error> { + async fn finger_response() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}FINGER\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1523,7 +1524,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn version_response() -> Result<(), failure::Error> { + async fn version_response() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}VERSION\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1543,7 +1544,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn source_response() -> Result<(), failure::Error> { + async fn source_response() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}SOURCE\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1560,7 +1561,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn ctcp_ping_response() -> Result<(), failure::Error> { + async fn ctcp_ping_response() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}PING test\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1577,7 +1578,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn time_response() -> Result<(), failure::Error> { + async fn time_response() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}TIME\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1593,7 +1594,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn user_info_response() -> Result<(), failure::Error> { + async fn user_info_response() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}USERINFO\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1611,7 +1612,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn ctcp_ping_no_timestamp() -> Result<(), failure::Error> { + async fn ctcp_ping_no_timestamp() -> Result<()> { let value = ":test!test@test PRIVMSG test :\u{001}PING\u{001}\r\n"; let mut client = Client::from_config(Config { mock_initial_value: Some(value.to_owned()), @@ -1624,7 +1625,7 @@ mod test { } #[tokio::test] - async fn identify() -> Result<(), failure::Error> { + async fn identify() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.identify()?; client.stream()?.collect().await?; @@ -1637,7 +1638,7 @@ mod test { } #[tokio::test] - async fn identify_with_password() -> Result<(), failure::Error> { + async fn identify_with_password() -> Result<()> { let mut client = Client::from_config(Config { nickname: Some(format!("test")), password: Some(format!("password")), @@ -1655,7 +1656,7 @@ mod test { } #[tokio::test] - async fn send_pong() -> Result<(), failure::Error> { + async fn send_pong() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_pong("irc.test.net")?; client.stream()?.collect().await?; @@ -1664,7 +1665,7 @@ mod test { } #[tokio::test] - async fn send_join() -> Result<(), failure::Error> { + async fn send_join() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_join("#test,#test2,#test3")?; client.stream()?.collect().await?; @@ -1676,7 +1677,7 @@ mod test { } #[tokio::test] - async fn send_part() -> Result<(), failure::Error> { + async fn send_part() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_part("#test")?; client.stream()?.collect().await?; @@ -1685,7 +1686,7 @@ mod test { } #[tokio::test] - async fn send_oper() -> Result<(), failure::Error> { + async fn send_oper() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_oper("test", "test")?; client.stream()?.collect().await?; @@ -1694,7 +1695,7 @@ mod test { } #[tokio::test] - async fn send_privmsg() -> Result<(), failure::Error> { + async fn send_privmsg() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_privmsg("#test", "Hi, everybody!")?; client.stream()?.collect().await?; @@ -1706,7 +1707,7 @@ mod test { } #[tokio::test] - async fn send_notice() -> Result<(), failure::Error> { + async fn send_notice() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_notice("#test", "Hi, everybody!")?; client.stream()?.collect().await?; @@ -1718,7 +1719,7 @@ mod test { } #[tokio::test] - async fn send_topic_no_topic() -> Result<(), failure::Error> { + async fn send_topic_no_topic() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_topic("#test", "")?; client.stream()?.collect().await?; @@ -1727,7 +1728,7 @@ mod test { } #[tokio::test] - async fn send_topic() -> Result<(), failure::Error> { + async fn send_topic() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_topic("#test", "Testing stuff.")?; client.stream()?.collect().await?; @@ -1739,7 +1740,7 @@ mod test { } #[tokio::test] - async fn send_kill() -> Result<(), failure::Error> { + async fn send_kill() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_kill("test", "Testing kills.")?; client.stream()?.collect().await?; @@ -1751,7 +1752,7 @@ mod test { } #[tokio::test] - async fn send_kick_no_message() -> Result<(), failure::Error> { + async fn send_kick_no_message() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_kick("#test", "test", "")?; client.stream()?.collect().await?; @@ -1760,7 +1761,7 @@ mod test { } #[tokio::test] - async fn send_kick() -> Result<(), failure::Error> { + async fn send_kick() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_kick("#test", "test", "Testing kicks.")?; client.stream()?.collect().await?; @@ -1772,7 +1773,7 @@ mod test { } #[tokio::test] - async fn send_mode_no_modeparams() -> Result<(), failure::Error> { + async fn send_mode_no_modeparams() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_mode("#test", &[Mode::Plus(ChannelMode::InviteOnly, None)])?; client.stream()?.collect().await?; @@ -1781,7 +1782,7 @@ mod test { } #[tokio::test] - async fn send_mode() -> Result<(), failure::Error> { + async fn send_mode() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_mode( "#test", @@ -1793,7 +1794,7 @@ mod test { } #[tokio::test] - async fn send_samode_no_modeparams() -> Result<(), failure::Error> { + async fn send_samode_no_modeparams() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_samode("#test", "+i", "")?; client.stream()?.collect().await?; @@ -1802,7 +1803,7 @@ mod test { } #[tokio::test] - async fn send_samode() -> Result<(), failure::Error> { + async fn send_samode() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_samode("#test", "+o", "test")?; client.stream()?.collect().await?; @@ -1811,7 +1812,7 @@ mod test { } #[tokio::test] - async fn send_sanick() -> Result<(), failure::Error> { + async fn send_sanick() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_sanick("test", "test2")?; client.stream()?.collect().await?; @@ -1820,7 +1821,7 @@ mod test { } #[tokio::test] - async fn send_invite() -> Result<(), failure::Error> { + async fn send_invite() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_invite("test", "#test")?; client.stream()?.collect().await?; @@ -1830,7 +1831,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_ctcp() -> Result<(), failure::Error> { + async fn send_ctcp() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_ctcp("test", "MESSAGE")?; client.stream()?.collect().await?; @@ -1843,7 +1844,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_action() -> Result<(), failure::Error> { + async fn send_action() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_action("test", "tests.")?; client.stream()?.collect().await?; @@ -1856,7 +1857,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_finger() -> Result<(), failure::Error> { + async fn send_finger() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_finger("test")?; client.stream()?.collect().await?; @@ -1869,7 +1870,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_version() -> Result<(), failure::Error> { + async fn send_version() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_version("test")?; client.stream()?.collect().await?; @@ -1882,7 +1883,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_source() -> Result<(), failure::Error> { + async fn send_source() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_source("test")?; client.stream()?.collect().await?; @@ -1895,7 +1896,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_user_info() -> Result<(), failure::Error> { + async fn send_user_info() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_user_info("test")?; client.stream()?.collect().await?; @@ -1908,7 +1909,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_ctcp_ping() -> Result<(), failure::Error> { + async fn send_ctcp_ping() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_ctcp_ping("test")?; client.stream()?.collect().await?; @@ -1921,7 +1922,7 @@ mod test { #[tokio::test] #[cfg(feature = "ctcp")] - async fn send_time() -> Result<(), failure::Error> { + async fn send_time() -> Result<()> { let mut client = Client::from_config(test_config()).await?; client.send_time("test")?; client.stream()?.collect().await?; diff --git a/src/error.rs b/src/error.rs index e060513..bafd1cf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,86 +3,77 @@ use std::io::Error as IoError; use std::sync::mpsc::RecvError; -use failure; use futures_channel::{ mpsc::{SendError, TrySendError}, oneshot::Canceled, }; -use native_tls::Error as TlsError; -#[cfg(feature = "json")] -use serde_json::Error as JsonError; -#[cfg(feature = "yaml")] -use serde_yaml::Error as YamlError; -#[cfg(feature = "toml")] -use toml::de::Error as TomlReadError; -#[cfg(feature = "toml")] -use toml::ser::Error as TomlWriteError; +use thiserror::Error; use crate::proto::error::{MessageParseError, ProtocolError}; /// A specialized `Result` type for the `irc` crate. -pub type Result = ::std::result::Result; +pub type Result = std::result::Result; /// The main crate-wide error type. -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum Error { /// An internal I/O error. - #[fail(display = "an io error occurred")] - Io(#[cause] IoError), + #[error("an io error occurred")] + Io(#[source] IoError), /// An internal TLS error. - #[fail(display = "a TLS error occurred")] - Tls(#[cause] TlsError), + #[error("a TLS error occurred")] + Tls(#[source] native_tls::Error), /// An internal synchronous channel closed. - #[fail(display = "a sync channel closed")] - SyncChannelClosed(#[cause] RecvError), + #[error("a sync channel closed")] + SyncChannelClosed(#[source] RecvError), /// An internal asynchronous channel closed. - #[fail(display = "an async channel closed")] - AsyncChannelClosed(#[cause] SendError), + #[error("an async channel closed")] + AsyncChannelClosed(#[source] SendError), /// An internal oneshot channel closed. - #[fail(display = "a oneshot channel closed")] - OneShotCanceled(#[cause] Canceled), + #[error("a oneshot channel closed")] + OneShotCanceled(#[source] Canceled), /// Error for invalid configurations. - #[fail(display = "invalid config: {}", path)] + #[error("invalid config: {}", path)] InvalidConfig { /// The path to the configuration, or "" if none specified. path: String, /// The detailed configuration error. - #[cause] + #[source] cause: ConfigError, }, /// Error for invalid messages. - #[fail(display = "invalid message: {}", string)] + #[error("invalid message: {}", string)] InvalidMessage { /// The string that failed to parse. string: String, /// The detailed message parsing error. - #[cause] + #[source] cause: MessageParseError, }, /// Mutex for a logged transport was poisoned making the log inaccessible. - #[fail(display = "mutex for a logged transport was poisoned")] + #[error("mutex for a logged transport was poisoned")] PoisonedLog, /// Ping timed out due to no response. - #[fail(display = "connection reset: no ping response")] + #[error("connection reset: no ping response")] PingTimeout, /// Failed to lookup an unknown codec. - #[fail(display = "unknown codec: {}", codec)] + #[error("unknown codec: {}", codec)] UnknownCodec { /// The attempted codec. codec: String, }, /// Failed to encode or decode something with the given codec. - #[fail(display = "codec {} failed: {}", codec, data)] + #[error("codec {} failed: {}", codec, data)] CodecFailed { /// The canonical codec name. codec: &'static str, @@ -91,78 +82,69 @@ pub enum Error { }, /// All specified nicknames were in use or unusable. - #[fail(display = "none of the specified nicknames were usable")] + #[error("none of the specified nicknames were usable")] NoUsableNick, /// Stream has already been configured. - #[fail(display = "stream has already been configured")] + #[error("stream has already been configured")] StreamAlreadyConfigured, - - /// This allows you to produce any `failure::Error` within closures used by - /// the irc crate. No errors of this kind will ever be produced by the crate - /// itself. - #[fail(display = "{}", inner)] - Custom { - /// The actual error that occurred. - inner: failure::Error, - }, } /// Errors that occur with configurations. -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum ConfigError { /// Failed to parse as TOML. #[cfg(feature = "toml")] - #[fail(display = "invalid toml")] - InvalidToml(#[cause] TomlError), + #[error("invalid toml")] + InvalidToml(#[source] TomlError), /// Failed to parse as JSON. #[cfg(feature = "json")] - #[fail(display = "invalid json")] - InvalidJson(#[cause] JsonError), + #[error("invalid json")] + InvalidJson(#[source] serde_json::Error), /// Failed to parse as YAML. #[cfg(feature = "yaml")] - #[fail(display = "invalid yaml")] - InvalidYaml(#[cause] YamlError), + #[error("invalid yaml")] + InvalidYaml(#[source] serde_yaml::Error), /// Failed to parse the given format because it was disabled at compile-time. - #[fail(display = "config format disabled: {}", format)] + #[error("config format disabled: {}", format)] ConfigFormatDisabled { /// The disabled file format. format: &'static str, }, /// Could not identify the given file format. - #[fail(display = "config format unknown: {}", format)] + #[error("config format unknown: {}", format)] UnknownConfigFormat { /// The unknown file extension. format: String, }, /// File was missing an extension to identify file format. - #[fail(display = "missing format extension")] + #[error("missing format extension")] MissingExtension, /// Configuration does not specify a nickname. - #[fail(display = "nickname not specified")] + #[error("nickname not specified")] NicknameNotSpecified, /// Configuration does not specify a server. - #[fail(display = "server not specified")] + #[error("server not specified")] ServerNotSpecified, } /// A wrapper that combines toml's serialization and deserialization errors. #[cfg(feature = "toml")] -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum TomlError { /// A TOML deserialization error. - #[fail(display = "deserialization failed")] - Read(#[cause] TomlReadError), + #[error("deserialization failed")] + Read(#[source] toml::de::Error), /// A TOML serialization error. - #[fail(display = "serialization failed")] - Write(#[cause] TomlWriteError), + #[error("serialization failed")] + Write(#[source] toml::ser::Error), } impl From for Error { @@ -182,8 +164,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: TlsError) -> Error { +impl From for Error { + fn from(e: native_tls::Error) -> Error { Error::Tls(e) } } diff --git a/src/lib.rs b/src/lib.rs index a3b1ce1..6bf9cc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,9 +43,6 @@ #![warn(missing_docs)] -#[macro_use] -extern crate failure; - pub extern crate irc_proto as proto; pub mod client;