User tracking keeps proper track of user rank now.
This commit is contained in:
parent
729ff3874c
commit
c669d44f15
3 changed files with 67 additions and 31 deletions
53
src/bot.rs
53
src/bot.rs
|
@ -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")]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
src/data.rs
42
src/data.rs
|
@ -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> {
|
||||||
|
|
|
@ -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>)> {
|
||||||
|
|
Loading…
Add table
Reference in a new issue