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 {Bot, process};
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 conn: Connection<T, U>,
pub config: Config,
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>> {
@ -87,6 +87,10 @@ impl<'a, T, U> Bot for IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader {
fn 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 {
@ -118,42 +122,29 @@ impl<'a, T, U> IrcBot<'a, T, U> where T: IrcWriter, U: IrcReader {
for user in users.split_str(" ") {
if !match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
Some(vec) => {
vec.push(String::from_str(user));
vec.push(User::new(user));
true
},
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]) => {
match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
Some(vec) => {
match source.find('!') {
Some(i) => vec.push(String::from_str(source.slice_to(i))),
None => (),
};
},
None => (),
if let Some(vec) = self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
if let Some(i) = source.find('!') {
vec.push(User::new(source[..i]))
}
}
},
("PART", [chan, _]) => {
match self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
Some(vec) => {
match source.find('!') {
Some(i) => {
match vec.as_slice().position_elem(&String::from_str(source.slice_to(i))) {
Some(n) => {
vec.swap_remove(n);
},
None => (),
};
},
None => (),
};
},
None => (),
if let Some(vec) = self.chanlists.borrow_mut().find_mut(&String::from_str(chan)) {
if let Some(i) = source.find('!') {
if let Some(n) = vec.as_slice().position_elem(&User::new(source[..i])) {
vec.swap_remove(n);
}
}
}
},
_ => {
@ -171,7 +162,7 @@ mod test {
use std::io::{BufReader, MemWriter};
use std::io::util::{NullReader, NullWriter};
use conn::Connection;
use data::IrcReader;
use data::{IrcReader, User};
fn data<U>(conn: Connection<MemWriter, U>) -> String where U: IrcReader {
String::from_utf8(conn.writer().deref_mut().get_ref().to_vec()).unwrap()
@ -305,7 +296,7 @@ mod test {
};
assert!(vec_res.is_ok());
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]
@ -320,7 +311,7 @@ mod test {
};
assert!(vec_res.is_ok());
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]
@ -336,6 +327,6 @@ mod test {
assert!(vec_res.is_ok());
let vec = vec_res.unwrap();
// 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 {}
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)]
pub struct Message<'a> {

View file

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