irc3 0.3.0

An IRC3 client and server toolchain
Documentation
pub mod conn;

use std::io::Error as IoError;
use std::pin::Pin;

use futures::stream::Stream;
use futures::sink::Sink;
use futures::task::{Context, Poll};

use super::proto::{
	transport::{MessageTransport, MessageTransportError},
	message::Message
};
use conn::Connection;

/// An IRC client wrapped around a TCP socket.
///
/// To interact with the client, the [`read_message`] and [`write_message`]
/// functions have been provided to interact with the connected server.
pub struct Client {
	conn: MessageTransport<Connection>,
}

impl Stream for Client {
	type Item = Result<Message, MessageTransportError>;

	fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
		Pin::new(&mut self.conn).poll_next(cx)
	}
}

impl Sink<Message> for Client {
	type Error = MessageTransportError;

	fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
		Pin::new(&mut self.conn).poll_ready(cx)
	}

	fn start_send(mut self: Pin<&mut Self>, msg: Message) -> Result<(), Self::Error> {
		Pin::new(&mut self.conn).start_send(msg)
	}
	
	fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
		Pin::new(&mut self.conn).poll_flush(cx)
	}
	
	fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
		Pin::new(&mut self.conn).poll_close(cx)
	}
}

impl Client {
	/// Create a new `Client`.
	/// 
	/// The client will establish a connection to a server and do nothing else. The function 
	/// expects a resolvable IP / DOMAIN in the form `<ip>[:<port>]` where `<port>` is
	/// optional (the default port for plaintext IRC is `6667`).
	pub async fn new<S: AsRef<str> + ?Sized>(dest: &S) -> Result<Client, IoError> {
		Ok(Client {
			conn: MessageTransport::new(Connection::unsecure(dest).await?),
		})
	}

	/// Create a new, secure `Client`.
	///
	/// This will preform a TLS handshake, and then return the result and do nothing else.
	/// The function expects a resolvable DOMAIN in the form `<domain>[:<port>]` where `<port>`
	/// is optional (the default port for encrypted IRC is `6697`).
	#[cfg(feature = "tls")]
	pub async fn new_secure<S: AsRef<str> + ?Sized>(dest: &S) -> Result<Client, IoError> {
		Ok(Client {
			conn: MessageTransport::new(Connection::secure(dest).await?),
		})
	}

	/// Read an IRC message directly from the underlying socket
	#[deprecated(since="0.2.0", note="use the `Stream`/`Sink` API instead")]
	#[allow(deprecated)]
	pub async fn read_message(&mut self) -> Result<Message, MessageTransportError> {
		self.conn.read_message().await
	}

	/// Write an IRC message directly to the underlying socket
	#[deprecated(since="0.2.0", note="use the `Stream`/`Sink` API instead")]
	#[allow(deprecated)]
	pub async fn write_message(&mut self, m: Message) -> Result<(), MessageTransportError> {
		self.conn.write_message(m).await
	}
}