Changed naming scheme from server to client (resolves #46).

This commit is contained in:
Aaron Weiss 2018-01-28 02:16:50 +01:00
parent 9c574b00c0
commit 87b84fdeb9
No known key found for this signature in database
GPG key ID: 047D32DF25DC22EF
12 changed files with 1473 additions and 135 deletions

View file

@ -24,25 +24,25 @@ fn main() {
let mut reactor = IrcReactor::new().unwrap();
for config in configs {
// Immediate errors like failure to resolve the server's name or to establish any connection will
// manifest here in the result of prepare_server_and_connect.
let server = reactor.prepare_server_and_connect(&config).unwrap();
server.identify().unwrap();
// Here, we tell the reactor to setup this server for future handling (in run) using the specified
// Immediate errors like failure to resolve the client's name or to establish any connection will
// manifest here in the result of prepare_client_and_connect.
let client = reactor.prepare_client_and_connect(&config).unwrap();
client.identify().unwrap();
// Here, we tell the reactor to setup this client for future handling (in run) using the specified
// handler function process_msg.
reactor.register_server_with_handler(server, process_msg);
reactor.register_client_with_handler(client, process_msg);
}
// Runtime errors like a dropped connection will manifest here in the result of run.
reactor.run().unwrap();
}
fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> {
fn process_msg(client: &IrcClient, message: Message) -> error::Result<()> {
print!("{}", message);
match message.command {
Command::PRIVMSG(ref target, ref msg) => {
if msg.contains("pickles") {
server.send_privmsg(target, "Hi!")?;
client.send_privmsg(target, "Hi!")?;
}
}
_ => (),

View file

@ -14,14 +14,14 @@ fn main() {
};
let mut reactor = IrcReactor::new().unwrap();
let server = reactor.prepare_server_and_connect(&config).unwrap();
server.identify().unwrap();
let client = reactor.prepare_client_and_connect(&config).unwrap();
client.identify().unwrap();
reactor.register_server_with_handler(server, |server, message| {
reactor.register_client_with_handler(client, |client, message| {
print!("{}", message);
if let Command::PRIVMSG(ref target, ref msg) = message.command {
if msg.contains("pickles") {
server.send_privmsg(target, "Hi!")?;
client.send_privmsg(target, "Hi!")?;
}
}
Ok(())

View file

@ -26,17 +26,17 @@ fn main() {
loop {
let res = configs.iter().fold(Ok(()), |acc, config| {
acc.and(
reactor.prepare_server_and_connect(config).and_then(|server| {
server.identify().and(Ok(server))
}).and_then(|server| {
reactor.register_server_with_handler(server, process_msg);
reactor.prepare_client_and_connect(config).and_then(|client| {
client.identify().and(Ok(client))
}).and_then(|client| {
reactor.register_client_with_handler(client, process_msg);
Ok(())
})
)
}).and_then(|()| reactor.run());
match res {
// The connections ended normally (for example, they sent a QUIT message to the server).
// The connections ended normally (for example, they sent a QUIT message to the client).
Ok(_) => break,
// Something went wrong! We'll print the error, and restart the connections.
Err(e) => eprintln!("{}", e),
@ -44,13 +44,13 @@ fn main() {
}
}
fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> {
fn process_msg(client: &IrcClient, message: Message) -> error::Result<()> {
print!("{}", message);
if let Command::PRIVMSG(ref target, ref msg) = message.command {
if msg.contains("pickles") {
server.send_privmsg(target, "Hi!")?;
client.send_privmsg(target, "Hi!")?;
} else if msg.contains("quit") {
server.send_quit("bye")?;
client.send_quit("bye")?;
}
}
Ok(())

View file

@ -15,19 +15,19 @@ fn main() {
..Default::default()
};
let server = IrcServer::from_config(config).unwrap();
server.identify().unwrap();
let client = IrcClient::from_config(config).unwrap();
client.identify().unwrap();
server.for_each_incoming(|message| {
client.for_each_incoming(|message| {
print!("{}", message);
if let Command::PRIVMSG(ref target, ref msg) = message.command {
if msg.starts_with(server.current_nickname()) {
if msg.starts_with(client.current_nickname()) {
let tokens: Vec<_> = msg.split(' ').collect();
if tokens.len() > 2 {
let n = tokens[0].len() + tokens[1].len() + 2;
if let Ok(count) = tokens[1].parse::<u8>() {
for _ in 0..count {
server.send_privmsg(
client.send_privmsg(
message.response_target().unwrap_or(target),
&msg[n..]
).unwrap();

View file

@ -12,14 +12,14 @@ fn main() {
..Default::default()
};
let server = IrcServer::from_config(config).unwrap();
server.identify().unwrap();
let client = IrcClient::from_config(config).unwrap();
client.identify().unwrap();
server.for_each_incoming(|message| {
client.for_each_incoming(|message| {
print!("{}", message);
if let Command::PRIVMSG(ref target, ref msg) = message.command {
if msg.contains("pickles") {
server.send_privmsg(target, "Hi!").unwrap();
client.send_privmsg(target, "Hi!").unwrap();
}
}
}).unwrap();

View file

@ -12,14 +12,14 @@ fn main() {
..Default::default()
};
let server = IrcServer::from_config(config).unwrap();
server.identify().unwrap();
let client = IrcClient::from_config(config).unwrap();
client.identify().unwrap();
server.for_each_incoming(|message| {
client.for_each_incoming(|message| {
print!("{}", message);
if let Command::PRIVMSG(ref target, ref msg) = message.command {
if msg.contains("pickles") {
server.send_privmsg(target, "Hi!").unwrap();
client.send_privmsg(target, "Hi!").unwrap();
}
}
}).unwrap();

View file

@ -12,15 +12,15 @@ fn main() {
channels: Some(vec!["#irc-crate".to_owned()]),
..Default::default()
};
let server = IrcServer::from_config(config).unwrap();
server.identify().unwrap();
let server2 = server.clone();
let client = IrcClient::from_config(config).unwrap();
client.identify().unwrap();
let client2 = client.clone();
// Let's set up a loop that just prints the messages.
thread::spawn(move || {
server2.stream().map(|m| print!("{}", m)).wait().count();
client2.stream().map(|m| print!("{}", m)).wait().count();
});
loop {
server.send_privmsg("#irc-crate", "TWEET TWEET").unwrap();
client.send_privmsg("#irc-crate", "TWEET TWEET").unwrap();
thread::sleep(Duration::new(10, 0));
}
}

View file

@ -1,8 +1,8 @@
//! Utilities and shortcuts for working with IRC servers.
//!
//! This module provides the [`ServerExt`](trait.ServerExt.html) trait which is the idiomatic way of
//! This module provides the [`ClientExt`](trait.ClientExt.html) trait which is the idiomatic way of
//! sending messages to an IRC server. This trait is automatically implemented for everything that
//! implements [`Server`](../trait.Server.html) and is designed to provide important functionality
//! implements [`Client`](../trait.Client.html) and is designed to provide important functionality
//! without clutter.
//!
//! # Examples
@ -12,17 +12,17 @@
//!
//! ```no_run
//! # extern crate irc;
//! use irc::client::prelude::{IrcServer, ServerExt};
//! use irc::client::prelude::{IrcClient, ClientExt};
//!
//! # fn main() {
//! let server = IrcServer::new("config.toml").unwrap();
//! // identify and send_privmsg both come from `ServerExt`
//! let server = IrcClient::new("config.toml").unwrap();
//! // identify and send_privmsg both come from `ClientExt`
//! server.identify().unwrap();
//! server.send_privmsg("#example", "Hello, world!").unwrap();
//! # }
//! ```
//!
//! `ServerExt::identify` also plays an important role in performing IRCv3 capability negotiations.
//! `ClientExt::identify` also plays an important role in performing IRCv3 capability negotiations.
//! In particular, calling `identify` will close the negotiations (and otherwise indicate IRCv3
//! compatibility). This means that all IRCv3 capability requests should be performed before calling
//! `identify`. For example:
@ -31,7 +31,7 @@
//! # extern crate irc;
//! # use irc::client::prelude::*;
//! # fn main() {
//! # let server = IrcServer::new("config.toml").unwrap();
//! # let server = IrcClient::new("config.toml").unwrap();
//! server.send_cap_req(&[Capability::MultiPrefix, Capability::UserhostInNames]).unwrap();
//! server.identify().unwrap();
//! # }
@ -46,10 +46,10 @@ use proto::{Capability, Command, Mode, NegotiationVersion};
use proto::command::CapSubCommand::{END, LS, REQ};
use proto::command::Command::*;
use proto::mode::ModeType;
use client::server::Server;
use client::Client;
/// Idiomatic extensions for sending messages to an IRC server.
pub trait ServerExt: Server {
pub trait ClientExt: Client {
/// Sends a request for a list of server capabilities for a specific IRCv3 version.
fn send_cap_ls(&self, version: NegotiationVersion) -> Result<()>
where
@ -377,23 +377,23 @@ pub trait ServerExt: Server {
}
}
impl<S> ServerExt for S
impl<S> ClientExt for S
where
S: Server,
S: Client,
{
}
#[cfg(test)]
mod test {
use super::ServerExt;
use super::ClientExt;
use client::data::Config;
use client::server::IrcServer;
use client::server::test::{get_server_value, test_config};
use client::IrcClient;
use client::test::{get_server_value, test_config};
use proto::{ChannelMode, Mode};
#[test]
fn identify() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.identify().unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -404,7 +404,7 @@ mod test {
#[test]
fn identify_with_password() {
let server = IrcServer::from_config(Config {
let server = IrcClient::from_config(Config {
nickname: Some(format!("test")),
password: Some(format!("password")),
..test_config()
@ -419,14 +419,14 @@ mod test {
#[test]
fn send_pong() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_pong("irc.test.net").unwrap();
assert_eq!(&get_server_value(server)[..], "PONG :irc.test.net\r\n");
}
#[test]
fn send_join() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_join("#test,#test2,#test3").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -436,21 +436,21 @@ mod test {
#[test]
fn send_part() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_part("#test").unwrap();
assert_eq!(&get_server_value(server)[..], "PART #test\r\n");
}
#[test]
fn send_oper() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_oper("test", "test").unwrap();
assert_eq!(&get_server_value(server)[..], "OPER test :test\r\n");
}
#[test]
fn send_privmsg() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_privmsg("#test", "Hi, everybody!").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -460,7 +460,7 @@ mod test {
#[test]
fn send_notice() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_notice("#test", "Hi, everybody!").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -470,14 +470,14 @@ mod test {
#[test]
fn send_topic_no_topic() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_topic("#test", "").unwrap();
assert_eq!(&get_server_value(server)[..], "TOPIC #test\r\n");
}
#[test]
fn send_topic() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_topic("#test", "Testing stuff.").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -487,7 +487,7 @@ mod test {
#[test]
fn send_kill() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_kill("test", "Testing kills.").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -497,14 +497,14 @@ mod test {
#[test]
fn send_kick_no_message() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_kick("#test", "test", "").unwrap();
assert_eq!(&get_server_value(server)[..], "KICK #test test\r\n");
}
#[test]
fn send_kick() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_kick("#test", "test", "Testing kicks.").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -514,14 +514,14 @@ mod test {
#[test]
fn send_mode_no_modeparams() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_mode("#test", &[Mode::Plus(ChannelMode::InviteOnly, None)]).unwrap();
assert_eq!(&get_server_value(server)[..], "MODE #test +i\r\n");
}
#[test]
fn send_mode() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_mode("#test", &[Mode::Plus(ChannelMode::Oper, Some("test".to_owned()))])
.unwrap();
assert_eq!(&get_server_value(server)[..], "MODE #test +o test\r\n");
@ -529,28 +529,28 @@ mod test {
#[test]
fn send_samode_no_modeparams() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_samode("#test", "+i", "").unwrap();
assert_eq!(&get_server_value(server)[..], "SAMODE #test +i\r\n");
}
#[test]
fn send_samode() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_samode("#test", "+o", "test").unwrap();
assert_eq!(&get_server_value(server)[..], "SAMODE #test +o test\r\n");
}
#[test]
fn send_sanick() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_sanick("test", "test2").unwrap();
assert_eq!(&get_server_value(server)[..], "SANICK test test2\r\n");
}
#[test]
fn send_invite() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_invite("test", "#test").unwrap();
assert_eq!(&get_server_value(server)[..], "INVITE test #test\r\n");
}
@ -558,7 +558,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_ctcp() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_ctcp("test", "MESSAGE").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -569,7 +569,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_action() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_action("test", "tests.").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -580,7 +580,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_finger() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_finger("test").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -591,7 +591,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_version() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_version("test").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -602,7 +602,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_source() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_source("test").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -613,7 +613,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_user_info() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_user_info("test").unwrap();
assert_eq!(
&get_server_value(server)[..],
@ -624,7 +624,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_ctcp_ping() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_ctcp_ping("test").unwrap();
let val = get_server_value(server);
println!("{}", val);
@ -635,7 +635,7 @@ mod test {
#[test]
#[cfg(feature = "ctcp")]
fn send_time() {
let server = IrcServer::from_config(test_config()).unwrap();
let server = IrcClient::from_config(test_config()).unwrap();
server.send_time("test").unwrap();
assert_eq!(
&get_server_value(server)[..],

File diff suppressed because it is too large Load diff

View file

@ -23,8 +23,8 @@
pub use client::data::Config;
pub use client::reactor::IrcReactor;
pub use client::server::{EachIncomingExt, IrcServer, Server};
pub use client::server::utils::ServerExt;
pub use client::{EachIncomingExt, IrcClient, Client};
pub use client::ext::ClientExt;
pub use proto::{Capability, ChannelExt, Command, Message, NegotiationVersion, Response};
pub use proto::{ChannelMode, Mode, UserMode};

View file

@ -1,8 +1,8 @@
//! A system for creating and managing IRC server connections.
//! A system for creating and managing IRC client connections.
//!
//! This API provides the ability to create and manage multiple IRC servers that can run on the same
//! This API provides the ability to create and manage multiple IRC clients that can run on the same
//! thread through the use of a shared event loop. It can also be used to encapsulate the dependency
//! on `tokio` and `futures` in the use of `IrcServer::new_future`. This means that knowledge of
//! on `tokio` and `futures` in the use of `IrcClient::new_future`. This means that knowledge of
//! those libraries should be unnecessary for the average user. Nevertheless, this API also provides
//! some escape hatches that let advanced users take further advantage of these dependencies.
//!
@ -16,11 +16,11 @@
//! fn main() {
//! let config = Config::default();
//! let mut reactor = IrcReactor::new().unwrap();
//! let server = reactor.prepare_server_and_connect(&config).unwrap();
//! reactor.register_server_with_handler(server, process_msg);
//! let client = reactor.prepare_client_and_connect(&config).unwrap();
//! reactor.register_client_with_handler(client, process_msg);
//! reactor.run().unwrap();
//! }
//! # fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> { Ok(()) }
//! # fn process_msg(client: &IrcClient, message: Message) -> error::Result<()> { Ok(()) }
//! ```
use futures::{Future, IntoFuture, Stream};
@ -28,14 +28,14 @@ use futures::future;
use tokio_core::reactor::{Core, Handle};
use client::data::Config;
use client::server::{IrcServer, IrcServerFuture, PackedIrcServer, Server};
use client::{IrcClient, IrcClientFuture, PackedIrcClient, Client};
use error;
use proto::Message;
/// A thin wrapper over an event loop.
///
/// An IRC reactor is used to create new connections to IRC servers and to drive the management of
/// all connected servers as the application runs. It can be used to run multiple servers on the
/// An IRC reactor is used to create new connections to IRC clients and to drive the management of
/// all connected clients as the application runs. It can be used to run multiple clients on the
/// same thread, as well as to get better control over error management in an IRC client.
///
/// For a full example usage, see [`irc::client::reactor`](./index.html).
@ -53,9 +53,9 @@ impl IrcReactor {
})
}
/// Creates a representation of an IRC server that has not yet attempted to connect. In
/// Creates a representation of an IRC client that has not yet attempted to connect. In
/// particular, this representation is as a Future that when run will produce a connected
/// [IrcServer](./server/struct.IrcServer.html).
/// [IrcClient](./client/struct.IrcClient.html).
///
/// # Example
/// ```no_run
@ -64,17 +64,17 @@ impl IrcReactor {
/// # use irc::client::prelude::*;
/// # fn main() {
/// # let config = Config::default();
/// let future_server = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_server(&config)
/// let future_client = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_client(&config)
/// });
/// # }
/// ```
pub fn prepare_server<'a>(&mut self, config: &'a Config) -> error::Result<IrcServerFuture<'a>> {
IrcServer::new_future(self.inner_handle(), config)
pub fn prepare_client<'a>(&mut self, config: &'a Config) -> error::Result<IrcClientFuture<'a>> {
IrcClient::new_future(self.inner_handle(), config)
}
/// Runs an [IrcServerFuture](./server/struct.IrcServerFuture.html), such as one from
/// `prepare_server` to completion, yielding an [IrcServer](./server/struct.IrcServer.html).
/// Runs an [IrcClientFuture](./client/struct.IrcClientFuture.html), such as one from
/// `prepare_client` to completion, yielding an [IrcClient](./client/struct.IrcClient.html).
///
/// # Example
/// ```no_run
@ -83,22 +83,22 @@ impl IrcReactor {
/// # use irc::client::prelude::*;
/// # fn main() {
/// # let config = Config::default();
/// let server = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_server(&config).and_then(|future| {
/// reactor.connect_server(future)
/// let client = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_client(&config).and_then(|future| {
/// reactor.connect_client(future)
/// })
/// });
/// # }
/// ```
pub fn connect_server(&mut self, future: IrcServerFuture) -> error::Result<IrcServer> {
self.inner.run(future).map(|PackedIrcServer(server, future)| {
pub fn connect_client(&mut self, future: IrcClientFuture) -> error::Result<IrcClient> {
self.inner.run(future).map(|PackedIrcClient(client, future)| {
self.register_future(future);
server
client
})
}
/// Creates a new IRC server from the specified configuration, connecting immediately. This is
/// guaranteed to be the composition of prepare_server and connect_server.
/// Creates a new IRC client from the specified configuration, connecting immediately. This is
/// guaranteed to be the composition of prepare_client and connect_client.
///
/// # Example
/// ```no_run
@ -107,16 +107,16 @@ impl IrcReactor {
/// # use irc::client::prelude::*;
/// # fn main() {
/// # let config = Config::default();
/// let server = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_server_and_connect(&config)
/// let client = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_client_and_connect(&config)
/// });
/// # }
/// ```
pub fn prepare_server_and_connect(&mut self, config: &Config) -> error::Result<IrcServer> {
self.prepare_server(config).and_then(|future| self.connect_server(future))
pub fn prepare_client_and_connect(&mut self, config: &Config) -> error::Result<IrcClient> {
self.prepare_client(config).and_then(|future| self.connect_client(future))
}
/// Registers the given server with the specified message handler. The reactor will store this
/// Registers the given client with the specified message handler. The reactor will store this
/// setup until the next call to run, where it will be used to process new messages over the
/// connection indefinitely (or until failure). As registration is consumed by `run`, subsequent
/// calls to run will require new registration.
@ -129,25 +129,25 @@ impl IrcReactor {
/// # fn main() {
/// # let config = Config::default();
/// let mut reactor = IrcReactor::new().unwrap();
/// let server = reactor.prepare_server_and_connect(&config).unwrap();
/// reactor.register_server_with_handler(server, |server, msg| {
/// let client = reactor.prepare_client_and_connect(&config).unwrap();
/// reactor.register_client_with_handler(client, |client, msg| {
/// // Message processing happens here.
/// Ok(())
/// })
/// # }
/// ```
pub fn register_server_with_handler<F, U>(
&mut self, server: IrcServer, handler: F
) where F: Fn(&IrcServer, Message) -> U + 'static,
pub fn register_client_with_handler<F, U>(
&mut self, client: IrcClient, handler: F
) where F: Fn(&IrcClient, Message) -> U + 'static,
U: IntoFuture<Item = (), Error = error::IrcError> + 'static {
self.handlers.push(Box::new(server.stream().for_each(move |message| {
handler(&server, message)
self.handlers.push(Box::new(client.stream().for_each(move |message| {
handler(&client, message)
})));
}
/// Registers an arbitrary future with this reactor. This is a sort of escape hatch that allows
/// you to take more control over what runs on the reactor without requiring you to bring in
/// additional knowledge about `tokio`. It is suspected that `register_server_with_handler` will
/// additional knowledge about `tokio`. It is suspected that `register_client_with_handler` will
/// be sufficient for most use cases.
pub fn register_future<F>(
&mut self, future: F
@ -163,8 +163,8 @@ impl IrcReactor {
}
/// Consumes all registered handlers and futures, and runs them. When using
/// `register_server_with_handler`, this will block indefinitely (until failure occurs) as it
/// will simply continue to process new, incoming messages for each server that was registered.
/// `register_client_with_handler`, this will block indefinitely (until failure occurs) as it
/// will simply continue to process new, incoming messages for each client that was registered.
///
/// # Example
/// ```no_run
@ -175,10 +175,10 @@ impl IrcReactor {
/// # fn main() {
/// # let config = Config::default();
/// let mut reactor = IrcReactor::new().unwrap();
/// let server = reactor.prepare_server_and_connect(&config).unwrap();
/// reactor.register_server_with_handler(server, process_msg)
/// let client = reactor.prepare_client_and_connect(&config).unwrap();
/// reactor.register_client_with_handler(client, process_msg)
/// # }
/// # fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> { Ok(()) }
/// # fn process_msg(client: &IrcClient, message: Message) -> error::Result<()> { Ok(()) }
/// ```
pub fn run(&mut self) -> error::Result<()> {
let mut handlers = Vec::new();

View file

@ -3,12 +3,12 @@
//! # Quick Start
//! The main public API is entirely exported in [`client::prelude`](./client/prelude/index.html). This
//! should include everything necessary to write an IRC client or bot.
//!
//!
//! # A Whirlwind Tour
//! The irc crate is divided into two main modules: [client](./client/index.html) and
//! [proto](./proto/index.html). As the names suggest, the client module captures the whole of the
//! client-side functionality, while the proto module features general components of an IRC protocol
//! implementation that could in principle be used in either client or server software. Both modules
//! implementation that could in principle be used in either client or client software. Both modules
//! feature a number of components that are low-level and can be used to build alternative APIs for
//! the IRC protocol. For the average user, the higher-level components for an IRC client are all
//! re-exported in [`client::prelude`](./client/prelude/index.html). That module serves as the best
@ -22,16 +22,16 @@
//!
//! # fn main() {
//! // configuration is loaded from config.toml into a Config
//! let server = IrcServer::new("config.toml").unwrap();
//! // identify comes from ServerExt
//! server.identify().unwrap();
//! // for_each_incoming comes from Server
//! server.for_each_incoming(|irc_msg| {
//! let client = IrcClient::new("config.toml").unwrap();
//! // identify comes from ClientExt
//! client.identify().unwrap();
//! // for_each_incoming comes from Client
//! client.for_each_incoming(|irc_msg| {
//! // irc_msg is a Message
//! match irc_msg.command {
//! Command::PRIVMSG(channel, message) => if message.contains(server.current_nickname()) {
//! // send_privmsg comes from ServerExt
//! server.send_privmsg(&channel, "beep boop").unwrap();
//! Command::PRIVMSG(channel, message) => if message.contains(client.current_nickname()) {
//! // send_privmsg comes from ClientExt
//! client.send_privmsg(&channel, "beep boop").unwrap();
//! }
//! _ => ()
//! }