diff --git a/.gitignore b/.gitignore
index c00c28f..dfb0af2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,4 @@
/irc-proto/target
/Cargo.lock
/irc-proto/Cargo.lock
-*.json
-*.toml
-*.yaml
!Cargo.toml
diff --git a/.travis.yml b/.travis.yml
index cc60af0..62e3949 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,17 +2,11 @@ language: rust
rust: stable
sudo: false
script:
- - chmod +x mktestconfig.sh
- - ./mktestconfig.sh
- - pushd irc-proto
- - cargo test --verbose
- - popd
- - cargo build --verbose
- - rustdoc --test README.md --extern irc=target/debug/libirc.rlib -L target/debug/deps
- - cargo test --verbose --features "toml yaml"
- - cargo test --doc
- - cargo test --verbose --no-default-features
- - cargo run --bin build-bot
+ - cargo test --all --features "toml yaml json"
+ - cargo build
+ # No idea how to fix this, since we don't depend on futures-preview directly.
+ # - rustdoc --test README.md --extern irc=target/debug/libirc.rlib -L target/debug/deps --edition 2018
+ - cargo run --example build-bot
notifications:
email: false
irc:
diff --git a/Cargo.toml b/Cargo.toml
index 3b5e45d..15719d2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,6 +9,7 @@ categories = ["asynchronous", "network-programming"]
documentation = "https://docs.rs/irc/"
repository = "https://github.com/aatxe/irc"
readme = "README.md"
+edition = "2018"
[badges]
travis-ci = { repository = "aatxe/irc" }
@@ -31,22 +32,25 @@ bytes = "0.4"
chrono = "0.4"
encoding = "0.2"
failure = "0.1"
-futures = "0.1"
irc-proto = { version = "*", path = "irc-proto" }
log = "0.4"
native-tls = "0.2"
-serde = "1.0"
+serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
+tokio = { version = "0.2.4", features = ["time", "net", "stream", "macros", "stream"] }
+tokio-util = { version = "0.2.0", features = ["codec"] }
+tokio-tls = "0.3.0"
serde_json = { version = "1.0", optional = true }
serde_yaml = { version = "0.7", optional = true }
-tokio = "0.1"
-tokio-codec = "0.1"
-tokio-io = "0.1"
-tokio-mockstream = "1.1"
-tokio-timer = "0.1"
-tokio-tls = "0.2"
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"
[dev-dependencies]
+futures = "0.3.1"
+anyhow = "1.0.13"
args = "2.0"
getopts = "0.2"
+env_logger = "0.6.2"
\ No newline at end of file
diff --git a/README.md b/README.md
index 84007cf..90510b2 100644
--- a/README.md
+++ b/README.md
@@ -48,21 +48,16 @@ documentation, and below.
[irc-prelude]: https://docs.rs/irc/*/irc/client/prelude/index.html
-## A Tale of Two APIs
+## Using Futures
-### Reactors (The "New" API)
-
-The release of v0.13 brought with it a new API called `IrcReactor` that enables easier multiserver
-support and more graceful error handling. The general model is that you use the reactor to create
-new `IrcClients`, register message handler functions, and finally block the thread to run the
-clients with their respective handlers. Here's an example:
-
-```rust,no_run
-extern crate irc;
+The release of v0.14 replaced all existing APIs with one based on async/await.
+```rust,no_run,edition2018
use irc::client::prelude::*;
+use futures::prelude::*;
-fn main() {
+#[tokio::main]
+async fn main() -> Result<(), failure::Error> {
// We can also load the Config at runtime via Config::load("path/to/config.toml")
let config = Config {
nickname: Some("the-irc-crate".to_owned()),
@@ -71,50 +66,16 @@ fn main() {
..Config::default()
};
- let mut reactor = IrcReactor::new().unwrap();
- let client = reactor.prepare_client_and_connect(config).unwrap();
- client.identify().unwrap();
+ let mut client = Client::from_config(config).await?;
+ client.identify()?;
- reactor.register_client_with_handler(client, |client, message| {
+ let mut stream = client.stream()?;
+
+ while let Some(message) = stream.next().await.transpose()? {
print!("{}", message);
- // And here we can do whatever we want with the messages.
- Ok(())
- });
+ }
- reactor.run().unwrap();
-}
-```
-
-
-### Direct Style (The "Old" API)
-
-The old API for connecting to an IRC server is still supported through the `IrcClient` type. It's
-simpler for the most basic use case, but will panic upon encountering any sort of connection issues.
-In general, it's recommended that users switch to the new API if possible. Nevertheless, here is an
-example:
-
-```rust,no_run
-extern crate irc;
-
-use std::default::Default;
-use irc::client::prelude::*;
-
-fn main() {
- // We can also load the Config at runtime via Config::load("path/to/config.toml")
- let cfg = Config {
- nickname: Some(format!("the-irc-crate")),
- server: Some(format!("irc.example.com")),
- channels: Some(vec![format!("#test")]),
- .. Default::default()
- };
-
- let client = IrcClient::from_config(cfg).unwrap();
- client.identify().unwrap();
-
- client.for_each_incoming(|message| {
- print!("{}", message);
- // And here we can do whatever we want with the messages.
- }).unwrap()
+ Ok(())
}
```
diff --git a/src/bin/build-bot.rs b/examples/build-bot.rs
similarity index 77%
rename from src/bin/build-bot.rs
rename to examples/build-bot.rs
index bf464ed..7d85030 100644
--- a/src/bin/build-bot.rs
+++ b/examples/build-bot.rs
@@ -1,10 +1,12 @@
extern crate irc;
+use futures::prelude::*;
use irc::client::prelude::*;
use std::default::Default;
use std::env;
-fn main() {
+#[tokio::main]
+async fn main() -> irc::error::Result<()> {
let repository_slug = env::var("TRAVIS_REPO_SLUG").unwrap();
let branch = env::var("TRAVIS_BRANCH").unwrap();
let commit = env::var("TRAVIS_COMMIT").unwrap();
@@ -17,11 +19,13 @@ fn main() {
..Default::default()
};
- let mut reactor = IrcReactor::new().unwrap();
- let client = reactor.prepare_client_and_connect(config).unwrap();
- client.identify().unwrap();
+ let mut client = Client::from_config(config).await?;
- reactor.register_client_with_handler(client, move |client, message| {
+ client.identify()?;
+
+ let mut stream = client.stream()?;
+
+ while let Some(message) = stream.next().await.transpose()? {
match message.command {
Command::Response(Response::RPL_ISUPPORT, _, _) => {
client.send_privmsg(
@@ -34,13 +38,12 @@ fn main() {
commit_message
),
)?;
+
client.send_quit("QUIT")?;
}
_ => (),
- };
+ }
+ }
- Ok(())
- });
-
- reactor.run().unwrap();
+ Ok(())
}
diff --git a/examples/convertconf.rs b/examples/convertconf.rs
index 24af879..ade8dc1 100644
--- a/examples/convertconf.rs
+++ b/examples/convertconf.rs
@@ -1,7 +1,3 @@
-extern crate args;
-extern crate getopts;
-extern crate irc;
-
use std::env;
use std::process::exit;
@@ -34,18 +30,22 @@ fn main() {
fn parse(input: &[String]) -> Result