User tracking keeps proper track of user rank now.

This commit is contained in:
Aaron Weiss 2014-10-27 00:33:17 -04:00
parent 729ff3874c
commit c669d44f15
3 changed files with 67 additions and 31 deletions

View file

@ -3,13 +3,13 @@ use std::collections::HashMap;
use std::io::{BufferedReader, BufferedWriter, IoResult, TcpStream}; use std::io::{BufferedReader, BufferedWriter, IoResult, TcpStream};
use {Bot, process}; use {Bot, process};
use conn::Connection; use conn::Connection;
use data::{Config, IrcReader, IrcWriter, Message}; use data::{Config, IrcReader, IrcWriter, Message, User};
pub struct IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader { pub struct IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader {
pub conn: Connection<T, U>, pub conn: Connection<T, U>,
pub config: Config, pub config: Config,
process: RefCell<|&IrcBot<T, U>, &str, &str, &[&str]|:'a -> IoResult<()>>, process: RefCell<|&IrcBot<T, U>, &str, &str, &[&str]|:'a -> IoResult<()>>,
pub chanlists: RefCell<HashMap<String, Vec<String>>>, chanlists: RefCell<HashMap<String, Vec<User>>>,
} }
impl<'a> IrcBot<'a, BufferedWriter<TcpStream>, BufferedReader<TcpStream>> { impl<'a> IrcBot<'a, BufferedWriter<TcpStream>, BufferedReader<TcpStream>> {
@ -87,6 +87,10 @@ impl<'a, T, U> Bot for IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader {
fn config(&self) -> &Config { fn config(&self) -> &Config {
&self.config &self.config
} }
fn get_users(&self, chan: &str) -> Option<Vec<User>> {
self.chanlists.borrow_mut().find_copy(&chan.into_string())
}
} }
impl<'a, T, U> IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader { impl<'a, T, U> IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader {
@ -118,42 +122,29 @@ impl<'a, T, U> IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader {
for user in users.split_str(" ") { for user in users.split_str(" ") {
if !match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) { if !match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
Some(vec) => { Some(vec) => {
vec.push(String::from_str(user)); vec.push(User::new(user));
true true
}, },
None => false, None => false,
} { } {
self.chanlists.borrow_mut().insert(String::from_str(chan), vec!(String::from_str(user))); self.chanlists.borrow_mut().insert(String::from_str(chan), vec!(User::new(user)));
} }
} }
}, },
("JOIN", [chan]) => { ("JOIN", [chan]) => {
match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) { if let Some(vec) = self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
Some(vec) => { if let Some(i) = source.find('!') {
match source.find('!') { vec.push(User::new(source[..i]))
Some(i) => vec.push(String::from_str(source.slice_to(i))), }
None => (),
};
},
None => (),
} }
}, },
("PART", [chan, _]) => { ("PART", [chan, _]) => {
match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) { if let Some(vec) = self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
Some(vec) => { if let Some(i) = source.find('!') {
match source.find('!') { if let Some(n) = vec.as_slice().position_elem(&User::new(source[..i])) {
Some(i) => { vec.swap_remove(n);
match vec.as_slice().position_elem(&String::from_str(source.slice_to(i))) { }
Some(n) => { }
vec.swap_remove(n);
},
None => (),
};
},
None => (),
};
},
None => (),
} }
}, },
_ => { _ => {
@ -171,7 +162,7 @@ mod test {
use std::io::{BufReader, MemWriter}; use std::io::{BufReader, MemWriter};
use std::io::util::{NullReader, NullWriter}; use std::io::util::{NullReader, NullWriter};
use conn::Connection; use conn::Connection;
use data::IrcReader; use data::{IrcReader, User};
fn data<U>(conn: Connection<MemWriter, U>) -> String where U: IrcReader { fn data<U>(conn: Connection<MemWriter, U>) -> String where U: IrcReader {
String::from_utf8(conn.writer().deref_mut().get_ref().to_vec()).unwrap() String::from_utf8(conn.writer().deref_mut().get_ref().to_vec()).unwrap()
@ -305,7 +296,7 @@ mod test {
}; };
assert!(vec_res.is_ok()); assert!(vec_res.is_ok());
let vec = vec_res.unwrap(); let vec = vec_res.unwrap();
assert_eq!(vec, vec![String::from_str("test"), String::from_str("test2"), String::from_str("test3")]); assert_eq!(vec, vec![User::new("test"), User::new("test2"), User::new("test3")]);
} }
#[test] #[test]
@ -320,7 +311,7 @@ mod test {
}; };
assert!(vec_res.is_ok()); assert!(vec_res.is_ok());
let vec = vec_res.unwrap(); let vec = vec_res.unwrap();
assert_eq!(vec, vec![String::from_str("test"), String::from_str("test2"), String::from_str("test3")]); assert_eq!(vec, vec![User::new("test"), User::new("test2"), User::new("test3")]);
} }
#[test] #[test]
@ -336,6 +327,6 @@ mod test {
assert!(vec_res.is_ok()); assert!(vec_res.is_ok());
let vec = vec_res.unwrap(); let vec = vec_res.unwrap();
// n.b. ordering is not guaranteed, this only ought to hold because we're removing the last user // n.b. ordering is not guaranteed, this only ought to hold because we're removing the last user
assert_eq!(vec, vec![String::from_str("test"), String::from_str("test2")]); assert_eq!(vec, vec![User::new("test"), User::new("test2")]);
} }
} }

View file

@ -7,6 +7,48 @@ impl<T> IrcWriter for T where T: Writer + Sized + 'static {}
pub trait IrcReader: Buffer + Sized + 'static {} pub trait IrcReader: Buffer + Sized + 'static {}
impl<T> IrcReader for T where T: Buffer + Sized + 'static {} impl<T> IrcReader for T where T: Buffer + Sized + 'static {}
#[deriving(PartialEq, Clone, Show)]
pub struct User {
name: String,
access_level: AccessLevel,
}
impl User {
pub fn new(name: &str) -> User {
let rank = AccessLevel::from_str(name);
User {
name: if let Member = rank {
name.into_string()
} else {
name[1..].into_string()
},
access_level: rank,
}
}
}
#[deriving(PartialEq, Clone, Show)]
pub enum AccessLevel {
Owner,
Admin,
Oper,
HalfOp,
Voice,
Member,
}
impl AccessLevel {
pub fn from_str(s: &str) -> AccessLevel {
match s.char_at(0) {
'~' => Owner,
'&' => Admin,
'@' => Oper,
'%' => HalfOp,
'+' => Voice,
_ => Member,
}
}
}
#[deriving(Show, PartialEq)] #[deriving(Show, PartialEq)]
pub struct Message<'a> { pub struct Message<'a> {

View file

@ -1,4 +1,6 @@
#![feature(if_let)]
#![feature(phase)] #![feature(phase)]
#![feature(slicing_syntax)]
extern crate regex; extern crate regex;
#[phase(plugin)] extern crate regex_macros; #[phase(plugin)] extern crate regex_macros;
extern crate serialize; extern crate serialize;
@ -22,6 +24,7 @@ pub trait Bot {
fn identify(&self) -> IoResult<()>; fn identify(&self) -> IoResult<()>;
fn output(&mut self) -> IoResult<()>; fn output(&mut self) -> IoResult<()>;
fn config(&self) -> &Config; fn config(&self) -> &Config;
fn get_users(&self, chan: &str) -> Option<Vec<data::User>>;
} }
fn process(msg: &str) -> IoResult<(&str, &str, Vec<&str>)> { fn process(msg: &str) -> IoResult<(&str, &str, Vec<&str>)> {