aboutsummaryrefslogtreecommitdiff
path: root/src/server.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.rs')
-rw-r--r--src/server.rs149
1 files changed, 65 insertions, 84 deletions
diff --git a/src/server.rs b/src/server.rs
index 154e517..9c4bb65 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -1,25 +1,19 @@
use std::io::{
- BufferedReader,
- TcpStream,
- IoError,
- IoResult
+ self,
+ Write,
+ Read,
+ BufRead,
+ BufReader,
};
-use std::mem;
-use callback::Callback;
+use std::net::TcpStream;
+
use message;
use message::{ Command, Message };
#[cfg(feature = "ssl")]
use openssl::ssl::{ SslContext, SslMethod, SslStream };
-#[derive(Show, PartialEq, Eq, Clone)]
-pub enum Failure {
- AlreadyConnected,
- NotConnected,
- Io(IoError)
-}
-
/// Yes, I don't like the name either, but it's private, so...
enum StreamKind {
Plain(TcpStream),
@@ -27,18 +21,26 @@ enum StreamKind {
Ssl(SslStream)
}
-impl Writer for StreamKind {
- fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+impl Write for StreamKind {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match *self {
StreamKind::Plain(ref mut s) => s.write(buf),
#[cfg(feature = "ssl")]
StreamKind::Ssl(ref mut s) => s.write(buf)
}
}
+
+ fn flush(&mut self) -> io::Result<()> {
+ match *self {
+ StreamKind::Plain(ref mut s) => s.flush(),
+ #[cfg(feature = "ssl")]
+ StreamKind::Ssl(ref mut s) => s.flush()
+ }
+ }
}
-impl Reader for StreamKind {
- fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+impl Read for StreamKind {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match *self {
StreamKind::Plain(ref mut s) => s.read(buf),
#[cfg(feature = "ssl")]
@@ -47,55 +49,41 @@ impl Reader for StreamKind {
}
}
-pub struct Event<'a> {
- pub server: &'a mut Server<'a>,
- pub message: &'a Message
-}
-
-pub struct Server<'a> {
+pub struct Server {
stream: Option<StreamKind>,
- pub events: Callback<Event<'a>>,
}
-impl<'a> Server<'a> {
- pub fn new() -> Server<'a> {
+impl Server {
+ pub fn new() -> Server {
Server {
- stream: None,
- events: {
- let mut c = Callback::new();
- c.register(Server::handle_event);
- c
- }
+ stream: None
}
}
- fn handle_event(e: &mut Event) {
- match e.message.command {
- Command::PING => {
- e.server.sendraw(format!("PONG :{}", message::join(e.message.content.clone(), 0)).as_slice(), true).unwrap();
- }
- _ => ()
+ fn handle_event(&mut self, msg: &message::Message) {
+ if *msg.command == "PING" {
+ let _ = self.send(Command::Pong { server1: msg.suffix.clone(), server2: None }.to_message());
}
}
- pub fn connect(&mut self, host: String, port: u16) -> Result<(), Failure> {
+ pub fn connect(&mut self, host: String, port: u16) -> ::Result<()> {
let s = &mut self.stream;
- match *s { Some(_) => return Err(Failure::AlreadyConnected), _ => () };
+ match *s { Some(_) => return Err(::IrscError::AlreadyConnected), _ => () };
*s = match TcpStream::connect((host.as_slice(), port)) {
Ok(tcp) => Some(StreamKind::Plain(tcp)),
- Err(e) => return Err(Failure::Io(e))
+ Err(e) => return Err(::IrscError::Io(e))
};
Ok(())
}
#[cfg(feature = "ssl")]
- pub fn connect_ssl(&mut self, host: String, port: u16) -> Result<(), Failure> {
+ pub fn connect_ssl(&mut self, host: String, port: u16) -> ::Result<()> {
let mut s = self.stream.lock();
- match *s { Some(_) => return Err(Failure::AlreadyConnected), _ => () };
+ match *s { Some(_) => return Err(::IrscError::AlreadyConnected), _ => () };
let tcp_stream = match TcpStream::connect((host.as_slice(), port)) {
Ok(tcp) => Some(tcp),
- Err(e) => return Err(Failure::Io(e))
+ Err(e) => return Err(::IrscError::Io(e))
};
let ssl = SslContext::new(SslMethod::Tlsv1);
@@ -103,87 +91,80 @@ impl<'a> Server<'a> {
*s = ssl_stream;
Ok(())
-
}
#[inline]
- fn sendraw(&mut self, s: &str, newline: bool) -> Result<(), Failure> {
+ fn sendraw(&mut self, s: &str, newline: bool) -> ::Result<usize> {
info!(">> {}", s);
- if cfg!(not(ndebug)) && s.len() > 510 {
+ if ::DEBUG && s.len() > 510 {
panic!("Message too long, kitties will die if this runs in release mode. Msg: {}", s)
}
let stream = &mut self.stream;
if stream.is_some() {
stream.as_mut().map(|stream| {
- match stream.write_str(s) {
- Ok(_) => match { if newline { stream.write_str("\r\n") } else { Ok(()) } } {
- Ok(_) => match stream.flush() {
- Ok(_) => Ok(()),
- Err(e) => return Err(Failure::Io(e))
+ match stream.write(s.as_bytes()) {
+ Ok(a) => match { if newline { stream.write(b"\r\n").map(|s| s + a) } else { Ok(a) } } {
+ Ok(b) => match stream.flush() {
+ Ok(_) => Ok(b),
+ Err(e) => return Err(::IrscError::Io(e))
},
- Err(e) => return Err(Failure::Io(e))
+ Err(e) => return Err(::IrscError::Io(e))
},
- Err(e) => return Err(Failure::Io(e))
+ Err(e) => return Err(::IrscError::Io(e))
}
}).unwrap()
} else {
- Err(Failure::NotConnected)
+ Err(::IrscError::NotConnected)
}
}
- pub fn send(&mut self, msg: message::Message) -> Result<(), Failure> {
- self.sendraw(msg.format()[], true)
+ pub fn send(&mut self, msg: message::Message) -> ::Result<usize> {
+ self.sendraw(&msg.to_string(), true)
}
- pub fn join(&mut self, channel: &str) -> Result<(), Failure> {
+ pub fn join(&mut self, channel: &str) -> ::Result<usize> {
self.sendraw(format!("JOIN {}", channel).as_slice(), true)
}
- pub fn part(&mut self, channel: &str) -> Result<(), Failure> {
+ pub fn part(&mut self, channel: &str) -> ::Result<usize> {
self.sendraw(format!("PART {}", channel).as_slice(), true)
}
- pub fn nick(&mut self, nick: &str) -> Result<(), Failure> {
+ pub fn nick(&mut self, nick: &str) -> ::Result<usize> {
self.sendraw(format!("NICK {}", nick).as_slice(), true)
}
- pub fn user(&mut self, username: &str, hostname: &str, servername: &str, realname: &str) -> Result<(), Failure> {
+ pub fn user(&mut self, username: &str, hostname: &str, servername: &str, realname: &str) -> ::Result<usize> {
self.sendraw(format!("USER {} {} {} :{}", username, hostname, servername, realname).as_slice(), true)
}
- pub fn password(&mut self, password: &str) -> Result<(), Failure> {
+ pub fn password(&mut self, password: &str) -> ::Result<usize> {
self.sendraw(format!("PASS {}", password).as_slice(), true)
}
- pub fn msg(&mut self, target: &str, message: &str) -> Result<(), Failure> {
+ pub fn msg(&mut self, target: &str, message: &str) -> ::Result<usize> {
self.sendraw(format!("PRIVMSG {} :{}", target, message).as_slice(), true)
}
- pub fn listen(&mut self) -> Result<(), Failure> {
- let stream = {
- match self.stream {
- Some(ref s) => s.clone(),
- None => return Err(Failure::NotConnected)
- }
- };
-
- let mut reader = BufferedReader::new(match *stream {
- StreamKind::Plain(ref s) => (*s).clone(),
+ pub fn listen(&mut self, events: &[fn(&mut Server, &Message)]) -> ::Result<()> {
+ let mut reader = BufReader::new(match self.stream {
+ Some(StreamKind::Plain(ref s)) => (*s).try_clone().unwrap(),
#[cfg(feature = "ssl")]
- StreamKind::Ssl(ref s) => (*s).clone()
+ Some(StreamKind::Ssl(ref s)) => (*s).try_clone().unwrap(),
+ None => return Err(::IrscError::NotConnected)
});
- loop {
- let line = reader.read_line().unwrap();
- info!("<< {}", line);
+ /*for line in reader.lines() {
+ let line = line.unwrap().parse();
- if let Some(msg) = Message::parse(line[]) {
- let mut e = self.events;
- e.fire(&mut Event {
- server: self,
- message: &msg
- });
+ if let Ok(msg) = line {
+ println!("{:?}", msg);
+ self.handle_event(&msg);
+ for e in events.iter() {
+ e(self, &msg)
+ }
}
- }
+ }*/
+ Ok(())
}
}