Added username and hostname parsing to User to better support
userhost-in-name extension.
This commit is contained in:
parent
f3a2417f6a
commit
a03e09264e
2 changed files with 42 additions and 14 deletions
|
@ -8,19 +8,30 @@ use std::str::FromStr;
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
/// The user's nickname.
|
/// The user's nickname.
|
||||||
/// This is the only detail used in determining the equality of two users.
|
nickname: String,
|
||||||
name: String,
|
/// The user's username.
|
||||||
|
username: Option<String>,
|
||||||
|
/// The user's hostname.
|
||||||
|
hostname: Option<String>,
|
||||||
/// The user's highest access level.
|
/// The user's highest access level.
|
||||||
highest_access_level: AccessLevel,
|
highest_access_level: AccessLevel,
|
||||||
|
/// All of the user's current access levels.
|
||||||
access_levels: Vec<AccessLevel>,
|
access_levels: Vec<AccessLevel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
/// Creates a new User.
|
/// Creates a new User.
|
||||||
pub fn new(name: &str) -> User {
|
pub fn new(string: &str) -> User {
|
||||||
let ranks: Vec<_> = AccessLevelIterator::new(name).collect();
|
let ranks: Vec<_> = AccessLevelIterator::new(string).collect();
|
||||||
|
let mut state = &string[ranks.len()..];
|
||||||
|
let nickname = state.find('!').map_or(state, |i| &state[..i]).to_owned();
|
||||||
|
state = state.find('!').map_or("", |i| &state[i+1..]);
|
||||||
|
let username = state.find('@').map(|i| state[..i].to_owned());
|
||||||
|
let hostname = state.find('@').map(|i| state[i+1..].to_owned());
|
||||||
User {
|
User {
|
||||||
name: name[ranks.len()..].to_owned(),
|
nickname: nickname,
|
||||||
|
username: username,
|
||||||
|
hostname: hostname,
|
||||||
access_levels: {
|
access_levels: {
|
||||||
let mut ranks = ranks.clone();
|
let mut ranks = ranks.clone();
|
||||||
ranks.push(AccessLevel::Member);
|
ranks.push(AccessLevel::Member);
|
||||||
|
@ -39,8 +50,20 @@ impl User {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the nickname of the user.
|
/// Gets the nickname of the user.
|
||||||
pub fn get_name(&self) -> &str {
|
pub fn get_nickname(&self) -> &str {
|
||||||
&self.name
|
&self.nickname
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the username of the user, if it's known.
|
||||||
|
/// This requires the IRCv3.2 extension `userhost-in-name`.
|
||||||
|
pub fn get_username(&self) -> Option<&str> {
|
||||||
|
self.username.as_ref().map(|s| &s[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the hostname of the user, if it's known.
|
||||||
|
/// This requires the IRCv3.2 extension `userhost-in-name`.
|
||||||
|
pub fn get_hostname(&self) -> Option<&str> {
|
||||||
|
self.hostname.as_ref().map(|s| &s[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the user's highest access level.
|
/// Gets the user's highest access level.
|
||||||
|
@ -99,7 +122,8 @@ impl User {
|
||||||
|
|
||||||
impl PartialEq for User {
|
impl PartialEq for User {
|
||||||
fn eq(&self, other: &User) -> bool {
|
fn eq(&self, other: &User) -> bool {
|
||||||
self.name == other.name
|
self.nickname == other.nickname && self.username == other.username &&
|
||||||
|
self.hostname == other.hostname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +239,9 @@ mod test {
|
||||||
fn create_user() {
|
fn create_user() {
|
||||||
let user = User::new("~owner");
|
let user = User::new("~owner");
|
||||||
let exp = User {
|
let exp = User {
|
||||||
name: format!("owner"),
|
nickname: format!("owner"),
|
||||||
|
username: None,
|
||||||
|
hostname: None,
|
||||||
highest_access_level: Owner,
|
highest_access_level: Owner,
|
||||||
access_levels: vec![Owner, Member],
|
access_levels: vec![Owner, Member],
|
||||||
};
|
};
|
||||||
|
@ -228,7 +254,9 @@ mod test {
|
||||||
fn create_user_complex() {
|
fn create_user_complex() {
|
||||||
let user = User::new("~&+user");
|
let user = User::new("~&+user");
|
||||||
let exp = User {
|
let exp = User {
|
||||||
name: format!("user"),
|
nickname: format!("user"),
|
||||||
|
username: None,
|
||||||
|
hostname: None,
|
||||||
highest_access_level: Owner,
|
highest_access_level: Owner,
|
||||||
access_levels: vec![Owner, Admin, Voice, Member]
|
access_levels: vec![Owner, Admin, Voice, Member]
|
||||||
};
|
};
|
||||||
|
@ -239,9 +267,9 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_name() {
|
fn get_nickname() {
|
||||||
let user = User::new("~owner");
|
let user = User::new("~owner");
|
||||||
assert_eq!(user.get_name(), "owner");
|
assert_eq!(user.get_nickname(), "owner");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -180,7 +180,7 @@ impl<T: IrcRead, U: IrcWrite> IrcServer<T, U> {
|
||||||
if &msg.command[..] == "JOIN" {
|
if &msg.command[..] == "JOIN" {
|
||||||
vec.push(User::new(&src[..i]));
|
vec.push(User::new(&src[..i]));
|
||||||
} else {
|
} else {
|
||||||
if let Some(n) = vec.iter().position(|x| x.get_name() == &src[..i]) {
|
if let Some(n) = vec.iter().position(|x| x.get_nickname() == &src[..i]) {
|
||||||
vec.swap_remove(n);
|
vec.swap_remove(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ impl<T: IrcRead, U: IrcWrite> IrcServer<T, U> {
|
||||||
let ref user = msg.args[2];
|
let ref user = msg.args[2];
|
||||||
if cfg!(not(feature = "nochanlists")) {
|
if cfg!(not(feature = "nochanlists")) {
|
||||||
if let Some(vec) = self.chanlists.lock().unwrap().get_mut(chan) {
|
if let Some(vec) = self.chanlists.lock().unwrap().get_mut(chan) {
|
||||||
if let Some(n) = vec.iter().position(|x| &x.get_name() == user) {
|
if let Some(n) = vec.iter().position(|x| &x.get_nickname() == user) {
|
||||||
vec[n].update_access_level(&mode);
|
vec[n].update_access_level(&mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue