From 567074a5991e8883245e67c51a7d4cfcaa3a05d1 Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Wed, 8 Oct 2014 12:57:36 -0400 Subject: [PATCH] Made changes to allow library to operate on any type of stream. --- src/conn.rs | 48 ++++++++++++++++++++++++++---------------------- src/lib.rs | 38 +++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/conn.rs b/src/conn.rs index b5093b8..069d2a2 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -1,30 +1,34 @@ -use std::io::{BufferedWriter, IoResult, TcpStream}; +use std::io::{BufferedWriter, IoResult, TcpStream, Writer}; use data::Message; -pub enum Connection { - TcpConn(TcpStream), +pub enum Connection where T: Writer + Sized + 'static, U: Reader + Sized + Clone + 'static { + Conn(T, U), } -pub fn connect(host: &str, port: u16) -> IoResult { - let socket = try!(TcpStream::connect(host, port)); - Ok(TcpConn(socket)) -} - -fn send_internal(conn: &Connection, msg: &str) -> IoResult<()> { - match conn { - &TcpConn(ref tcp) => { - let mut writer = BufferedWriter::new(tcp.clone()); - writer.write_str(msg) - } +impl Connection, TcpStream> { + pub fn connect(host: &str, port: u16) -> IoResult, TcpStream>> { + let socket = try!(TcpStream::connect(host, port)); + Ok(Conn(BufferedWriter::new(socket.clone()), socket.clone())) } } -pub fn send(conn: &Connection, msg: Message) -> IoResult<()> { - let mut send = msg.command.to_string(); - send.push_str(" "); - send.push_str(msg.args.init().connect(" ").as_slice()); - send.push_str(" :"); - send.push_str(*msg.args.last().unwrap()); - send.push_str("\r\n"); - send_internal(conn, send.as_slice()) +impl Connection where T: Writer + Sized + 'static, U: Reader + Sized + Clone + 'static { + fn send_internal(conn: &mut Connection, msg: &str) -> IoResult<()> { + match conn { + &Conn(ref mut send, _) => { + try!(send.write_str(msg)); + send.flush() + } + } + } + + pub fn send(conn: &mut Connection, msg: Message) -> IoResult<()> { + let mut send = msg.command.to_string(); + send.push_str(" "); + send.push_str(msg.args.init().connect(" ").as_slice()); + send.push_str(" :"); + send.push_str(*msg.args.last().unwrap()); + send.push_str("\r\n"); + Connection::send_internal(conn, send.as_slice()) + } } diff --git a/src/lib.rs b/src/lib.rs index 3f19e0c..fe361ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,27 +5,27 @@ extern crate serialize; use std::cell::RefCell; use std::collections::HashMap; -use std::io::{BufferedReader, InvalidInput, IoError, IoResult}; +use std::io::{BufferedReader, BufferedWriter, InvalidInput, IoError, IoResult, TcpStream}; use std::vec::Vec; -use conn::{Connection, TcpConn, connect, send}; +use conn::{Conn, Connection}; use data::{Config, Message}; pub mod conn; pub mod data; -pub struct Bot<'a> { - pub conn: Connection, +pub struct Bot<'a, T, U> where T: Writer + Sized + 'static, U: Reader + Sized + Clone + 'static { + pub conn: RefCell>, pub config: Config, - process: RefCell<|&Bot, &str, &str, &[&str]|:'a -> IoResult<()>>, + process: RefCell<|&Bot, &str, &str, &[&str]|:'a -> IoResult<()>>, pub chanlists: HashMap>, } -impl<'a> Bot<'a> { - pub fn new(process: |&Bot, &str, &str, &[&str]|:'a -> IoResult<()>) -> IoResult> { +impl<'a, T, U> Bot<'a, T, U> where T: Writer + Sized + 'static, U: Buffer + Sized + Clone + 'static { + pub fn new(process: |&Bot, TcpStream>, &str, &str, &[&str]|:'a -> IoResult<()>) -> IoResult, TcpStream>> { let config = try!(Config::load()); - let conn = try!(connect(config.server.as_slice(), config.port)); + let conn = try!(Connection::connect(config.server.as_slice(), config.port)); Ok(Bot { - conn: conn, + conn: RefCell::new(conn), config: config, process: RefCell::new(process), chanlists: HashMap::new(), @@ -33,31 +33,31 @@ impl<'a> Bot<'a> { } pub fn send_nick(&self, nick: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "NICK", [nick])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "NICK", [nick])) } pub fn send_user(&self, username: &str, real_name: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "USER", [username, "0", "*", real_name])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "USER", [username, "0", "*", real_name])) } pub fn send_join(&self, chan: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "JOIN", [chan.as_slice()])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "JOIN", [chan.as_slice()])) } pub fn send_mode(&self, chan: &str, mode: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "MODE", [chan.as_slice(), mode.as_slice()])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "MODE", [chan.as_slice(), mode.as_slice()])) } pub fn send_topic(&self, chan: &str, topic: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "TOPIC", [chan.as_slice(), topic.as_slice()])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "TOPIC", [chan.as_slice(), topic.as_slice()])) } pub fn send_invite(&self, person: &str, chan: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "INVITE", [person.as_slice(), chan.as_slice()])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "INVITE", [person.as_slice(), chan.as_slice()])) } pub fn send_privmsg(&self, chan: &str, msg: &str) -> IoResult<()> { - send(&self.conn, Message::new(None, "PRIVMSG", [chan.as_slice(), msg.as_slice()])) + Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "PRIVMSG", [chan.as_slice(), msg.as_slice()])) } pub fn identify(&self) -> IoResult<()> { @@ -66,8 +66,8 @@ impl<'a> Bot<'a> { } pub fn output(&mut self) -> IoResult<()> { - let mut reader = match self.conn { - TcpConn(ref tcp) => BufferedReader::new(tcp.clone()), + let mut reader = match self.conn.borrow_mut().deref_mut() { + &Conn(_, ref recv) => BufferedReader::new(recv.clone()), }; for line in reader.lines() { match line { @@ -85,7 +85,7 @@ impl<'a> Bot<'a> { fn handle_command(&mut self, source: &str, command: &str, args: &[&str]) -> IoResult<()> { match (command, args) { ("PING", [msg]) => { - try!(send(&self.conn, Message::new(None, "PONG", [msg]))); + try!(Connection::send(self.conn.borrow_mut().deref_mut(), Message::new(None, "PONG", [msg]))); }, ("376", _) => { // End of MOTD for chan in self.config.channels.iter() {