Merge pull request #155 from theduke/owned-config

Refactor IrcClientFuture and ConnectionFuture to own the config
This commit is contained in:
Aaron Weiss 2018-10-03 21:13:57 -04:00 committed by GitHub
commit 8d054dc281
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 41 additions and 42 deletions

View file

@ -70,7 +70,7 @@ fn main() {
}; };
let mut reactor = IrcReactor::new().unwrap(); let mut reactor = IrcReactor::new().unwrap();
let client = reactor.prepare_client_and_connect(&config).unwrap(); let client = reactor.prepare_client_and_connect(config).unwrap();
client.identify().unwrap(); client.identify().unwrap();
reactor.register_client_with_handler(client, |client, message| { reactor.register_client_with_handler(client, |client, message| {

View file

@ -26,7 +26,7 @@ fn main() {
for config in configs { for config in configs {
// Immediate errors like failure to resolve the server's domain or to establish any connection will // Immediate errors like failure to resolve the server's domain or to establish any connection will
// manifest here in the result of prepare_client_and_connect. // manifest here in the result of prepare_client_and_connect.
let client = reactor.prepare_client_and_connect(&config).unwrap(); let client = reactor.prepare_client_and_connect(config).unwrap();
client.identify().unwrap(); client.identify().unwrap();
// Here, we tell the reactor to setup this client for future handling (in run) using the specified // Here, we tell the reactor to setup this client for future handling (in run) using the specified
// handler function process_msg. // handler function process_msg.

View file

@ -14,7 +14,7 @@ fn main() {
}; };
let mut reactor = IrcReactor::new().unwrap(); let mut reactor = IrcReactor::new().unwrap();
let client = reactor.prepare_client_and_connect(&config).unwrap(); let client = reactor.prepare_client_and_connect(config).unwrap();
client.identify().unwrap(); client.identify().unwrap();
reactor.register_client_with_handler(client, |client, message| { reactor.register_client_with_handler(client, |client, message| {

View file

@ -26,7 +26,7 @@ fn main() {
loop { loop {
let res = configs.iter().fold(Ok(()), |acc, config| { let res = configs.iter().fold(Ok(()), |acc, config| {
acc.and( acc.and(
reactor.prepare_client_and_connect(&config).and_then(|client| { reactor.prepare_client_and_connect(config.clone()).and_then(|client| {
client.identify().and(Ok(client)) client.identify().and(Ok(client))
}).and_then(|client| { }).and_then(|client| {
reactor.register_client_with_handler(client, process_msg); reactor.register_client_with_handler(client, process_msg);

View file

@ -18,7 +18,7 @@ fn main() {
// We need to create a reactor first and foremost // We need to create a reactor first and foremost
let mut reactor = IrcReactor::new().unwrap(); let mut reactor = IrcReactor::new().unwrap();
// and then create a client via its API. // and then create a client via its API.
let client = reactor.prepare_client_and_connect(&config).unwrap(); let client = reactor.prepare_client_and_connect(config).unwrap();
// Then, we identify // Then, we identify
client.identify().unwrap(); client.identify().unwrap();
// and clone just as before. // and clone just as before.

View file

@ -8,7 +8,8 @@ use encoding::label::encoding_from_whatwg_label;
use futures::{Async, Poll, Future, Sink, StartSend, Stream}; use futures::{Async, Poll, Future, Sink, StartSend, Stream};
use native_tls::{Certificate, TlsConnector, Identity}; use native_tls::{Certificate, TlsConnector, Identity};
use tokio_codec::Decoder; use tokio_codec::Decoder;
use tokio::net::{TcpStream, ConnectFuture}; use tokio::net::{TcpStream};
use tokio::net::tcp::ConnectFuture;
use tokio_mockstream::MockStream; use tokio_mockstream::MockStream;
use tokio_tls::{self, TlsStream}; use tokio_tls::{self, TlsStream};
@ -45,16 +46,16 @@ impl fmt::Debug for Connection {
type TlsFuture = Box<Future<Error = error::IrcError, Item = TlsStream<TcpStream>> + Send>; type TlsFuture = Box<Future<Error = error::IrcError, Item = TlsStream<TcpStream>> + Send>;
/// A future representing an eventual `Connection`. /// A future representing an eventual `Connection`.
pub enum ConnectionFuture<'a> { pub enum ConnectionFuture {
#[doc(hidden)] #[doc(hidden)]
Unsecured(&'a Config, ConnectFuture), Unsecured(Config, ConnectFuture),
#[doc(hidden)] #[doc(hidden)]
Secured(&'a Config, TlsFuture), Secured(Config, TlsFuture),
#[doc(hidden)] #[doc(hidden)]
Mock(&'a Config), Mock(Config),
} }
impl<'a> fmt::Debug for ConnectionFuture<'a> { impl fmt::Debug for ConnectionFuture {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
@ -65,35 +66,35 @@ impl<'a> fmt::Debug for ConnectionFuture<'a> {
ConnectionFuture::Mock(_) => "ConnectionFuture::Mock", ConnectionFuture::Mock(_) => "ConnectionFuture::Mock",
}, },
match *self { match *self {
ConnectionFuture::Unsecured(cfg, _) | ConnectionFuture::Unsecured(ref cfg, _) |
ConnectionFuture::Secured(cfg, _) | ConnectionFuture::Secured(ref cfg, _) |
ConnectionFuture::Mock(cfg) => cfg, ConnectionFuture::Mock(ref cfg) => cfg,
} }
) )
} }
} }
impl<'a> Future for ConnectionFuture<'a> { impl Future for ConnectionFuture {
type Item = Connection; type Item = Connection;
type Error = error::IrcError; type Error = error::IrcError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match *self { match *self {
ConnectionFuture::Unsecured(config, ref mut inner) => { ConnectionFuture::Unsecured(ref config, ref mut inner) => {
let stream = try_ready!(inner.poll()); let stream = try_ready!(inner.poll());
let framed = IrcCodec::new(config.encoding())?.framed(stream); let framed = IrcCodec::new(config.encoding())?.framed(stream);
let transport = IrcTransport::new(config, framed); let transport = IrcTransport::new(&config, framed);
Ok(Async::Ready(Connection::Unsecured(transport))) Ok(Async::Ready(Connection::Unsecured(transport)))
} }
ConnectionFuture::Secured(config, ref mut inner) => { ConnectionFuture::Secured(ref config, ref mut inner) => {
let stream = try_ready!(inner.poll()); let stream = try_ready!(inner.poll());
let framed = IrcCodec::new(config.encoding())?.framed(stream); let framed = IrcCodec::new(config.encoding())?.framed(stream);
let transport = IrcTransport::new(config, framed); let transport = IrcTransport::new(&config, framed);
Ok(Async::Ready(Connection::Secured(transport))) Ok(Async::Ready(Connection::Secured(transport)))
} }
ConnectionFuture::Mock(config) => { ConnectionFuture::Mock(ref config) => {
let enc: error::Result<_> = encoding_from_whatwg_label( let enc: error::Result<_> = encoding_from_whatwg_label(
config.encoding() config.encoding()
).ok_or_else(|| error::IrcError::UnknownCodec { ).ok_or_else(|| error::IrcError::UnknownCodec {
@ -112,7 +113,7 @@ impl<'a> Future for ConnectionFuture<'a> {
let stream = MockStream::new(&initial?); let stream = MockStream::new(&initial?);
let framed = IrcCodec::new(config.encoding())?.framed(stream); let framed = IrcCodec::new(config.encoding())?.framed(stream);
let transport = IrcTransport::new(config, framed); let transport = IrcTransport::new(&config, framed);
Ok(Async::Ready(Connection::Mock(Logged::wrap(transport)))) Ok(Async::Ready(Connection::Mock(Logged::wrap(transport))))
} }
@ -122,7 +123,7 @@ impl<'a> Future for ConnectionFuture<'a> {
impl Connection { impl Connection {
/// Creates a new `Connection` using the specified `Config` /// Creates a new `Connection` using the specified `Config`
pub fn new<'a>(config: &'a Config) -> error::Result<ConnectionFuture<'a>> { pub fn new(config: Config) -> error::Result<ConnectionFuture> {
if config.use_mock_connection() { if config.use_mock_connection() {
Ok(ConnectionFuture::Mock(config)) Ok(ConnectionFuture::Mock(config))
} else if config.use_ssl() { } else if config.use_ssl() {
@ -158,9 +159,10 @@ impl Connection {
Ok(ConnectionFuture::Secured(config, stream)) Ok(ConnectionFuture::Secured(config, stream))
} else { } else {
info!("Connecting to {}.", config.server()?); info!("Connecting to {}.", config.server()?);
let addr = config.socket_addr()?;
Ok(ConnectionFuture::Unsecured( Ok(ConnectionFuture::Unsecured(
config, config,
TcpStream::connect(&config.socket_addr()?), TcpStream::connect(&addr),
)) ))
} }
} }

View file

@ -696,7 +696,7 @@ impl IrcClient {
let _ = thread::spawn(move || { let _ = thread::spawn(move || {
let mut reactor = Runtime::new().unwrap(); let mut reactor = Runtime::new().unwrap();
// Setting up internal processing stuffs. // Setting up internal processing stuffs.
let conn = reactor.block_on(Connection::new(&cfg).unwrap()).unwrap(); let conn = reactor.block_on(Connection::new(cfg.clone()).unwrap()).unwrap();
tx_view.send(conn.log_view()).unwrap(); tx_view.send(conn.log_view()).unwrap();
let (sink, stream) = conn.split(); let (sink, stream) = conn.split();
@ -745,7 +745,7 @@ impl IrcClient {
/// # .. Default::default() /// # .. Default::default()
/// # }; /// # };
/// let mut reactor = Runtime::new().unwrap(); /// let mut reactor = Runtime::new().unwrap();
/// let future = IrcClient::new_future(&config).unwrap(); /// let future = IrcClient::new_future(config).unwrap();
/// // immediate connection errors (like no internet) will turn up here... /// // immediate connection errors (like no internet) will turn up here...
/// let PackedIrcClient(client, future) = reactor.block_on(future).unwrap(); /// let PackedIrcClient(client, future) = reactor.block_on(future).unwrap();
/// // runtime errors (like disconnections and so forth) will turn up here... /// // runtime errors (like disconnections and so forth) will turn up here...
@ -756,11 +756,11 @@ impl IrcClient {
/// # } /// # }
/// # fn process_msg(server: &IrcClient, message: Message) -> error::Result<()> { Ok(()) } /// # fn process_msg(server: &IrcClient, message: Message) -> error::Result<()> { Ok(()) }
/// ``` /// ```
pub fn new_future(config: &Config) -> error::Result<IrcClientFuture> { pub fn new_future(config: Config) -> error::Result<IrcClientFuture> {
let (tx_outgoing, rx_outgoing) = mpsc::unbounded(); let (tx_outgoing, rx_outgoing) = mpsc::unbounded();
Ok(IrcClientFuture { Ok(IrcClientFuture {
conn: Connection::new(config)?, conn: Connection::new(config.clone())?,
config: config, config: config,
tx_outgoing: Some(tx_outgoing), tx_outgoing: Some(tx_outgoing),
rx_outgoing: Some(rx_outgoing), rx_outgoing: Some(rx_outgoing),
@ -789,14 +789,14 @@ impl IrcClient {
/// [`tokio`](https://tokio.rs/docs/getting-started/futures/). An easy to use abstraction that does /// [`tokio`](https://tokio.rs/docs/getting-started/futures/). An easy to use abstraction that does
/// not require this knowledge is available via [`IrcReactors`](./reactor/struct.IrcReactor.html). /// not require this knowledge is available via [`IrcReactors`](./reactor/struct.IrcReactor.html).
#[derive(Debug)] #[derive(Debug)]
pub struct IrcClientFuture<'a> { pub struct IrcClientFuture {
conn: ConnectionFuture<'a>, conn: ConnectionFuture,
config: &'a Config, config: Config,
tx_outgoing: Option<UnboundedSender<Message>>, tx_outgoing: Option<UnboundedSender<Message>>,
rx_outgoing: Option<UnboundedReceiver<Message>>, rx_outgoing: Option<UnboundedReceiver<Message>>,
} }
impl<'a> Future for IrcClientFuture<'a> { impl Future for IrcClientFuture {
type Item = PackedIrcClient; type Item = PackedIrcClient;
type Error = error::IrcError; type Error = error::IrcError;

View file

@ -16,7 +16,7 @@
//! fn main() { //! fn main() {
//! let config = Config::default(); //! let config = Config::default();
//! let mut reactor = IrcReactor::new().unwrap(); //! let mut reactor = IrcReactor::new().unwrap();
//! let client = reactor.prepare_client_and_connect(&config).unwrap(); //! let client = reactor.prepare_client_and_connect(config).unwrap();
//! reactor.register_client_with_handler(client, process_msg); //! reactor.register_client_with_handler(client, process_msg);
//! reactor.run().unwrap(); //! reactor.run().unwrap();
//! } //! }
@ -63,13 +63,12 @@ impl IrcReactor {
/// # use std::default::Default; /// # use std::default::Default;
/// # use irc::client::prelude::*; /// # use irc::client::prelude::*;
/// # fn main() { /// # fn main() {
/// # let config = Config::default();
/// let future_client = IrcReactor::new().and_then(|mut reactor| { /// let future_client = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_client(&config) /// reactor.prepare_client(Config::default())
/// }); /// });
/// # } /// # }
/// ``` /// ```
pub fn prepare_client<'a>(&mut self, config: &'a Config) -> error::Result<IrcClientFuture<'a>> { pub fn prepare_client(&mut self, config: Config) -> error::Result<IrcClientFuture> {
IrcClient::new_future(config) IrcClient::new_future(config)
} }
@ -82,9 +81,8 @@ impl IrcReactor {
/// # use std::default::Default; /// # use std::default::Default;
/// # use irc::client::prelude::*; /// # use irc::client::prelude::*;
/// # fn main() { /// # fn main() {
/// # let config = Config::default();
/// let client = IrcReactor::new().and_then(|mut reactor| { /// let client = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_client(&config).and_then(|future| { /// reactor.prepare_client(Config::default()).and_then(|future| {
/// reactor.connect_client(future) /// reactor.connect_client(future)
/// }) /// })
/// }); /// });
@ -107,13 +105,12 @@ impl IrcReactor {
/// # use std::default::Default; /// # use std::default::Default;
/// # use irc::client::prelude::*; /// # use irc::client::prelude::*;
/// # fn main() { /// # fn main() {
/// # let config = Config::default();
/// let client = IrcReactor::new().and_then(|mut reactor| { /// let client = IrcReactor::new().and_then(|mut reactor| {
/// reactor.prepare_client_and_connect(&config) /// reactor.prepare_client_and_connect(Config::default())
/// }); /// });
/// # } /// # }
/// ``` /// ```
pub fn prepare_client_and_connect(&mut self, config: &Config) -> error::Result<IrcClient> { pub fn prepare_client_and_connect(&mut self, config: Config) -> error::Result<IrcClient> {
self.prepare_client(config).and_then(|future| self.connect_client(future)) self.prepare_client(config).and_then(|future| self.connect_client(future))
} }
@ -130,7 +127,7 @@ impl IrcReactor {
/// # fn main() { /// # fn main() {
/// # let config = Config::default(); /// # let config = Config::default();
/// let mut reactor = IrcReactor::new().unwrap(); /// let mut reactor = IrcReactor::new().unwrap();
/// let client = reactor.prepare_client_and_connect(&config).unwrap(); /// let client = reactor.prepare_client_and_connect(config).unwrap();
/// reactor.register_client_with_handler(client, |client, msg| { /// reactor.register_client_with_handler(client, |client, msg| {
/// // Message processing happens here. /// // Message processing happens here.
/// Ok(()) /// Ok(())
@ -176,7 +173,7 @@ impl IrcReactor {
/// # fn main() { /// # fn main() {
/// # let config = Config::default(); /// # let config = Config::default();
/// let mut reactor = IrcReactor::new().unwrap(); /// let mut reactor = IrcReactor::new().unwrap();
/// let client = reactor.prepare_client_and_connect(&config).unwrap(); /// let client = reactor.prepare_client_and_connect(config).unwrap();
/// reactor.register_client_with_handler(client, process_msg); /// reactor.register_client_with_handler(client, process_msg);
/// reactor.run().unwrap(); /// reactor.run().unwrap();
/// # } /// # }