Ran rustfmt on all the code.
This commit is contained in:
parent
388628d62a
commit
f0f0b95038
15 changed files with 1953 additions and 1178 deletions
File diff suppressed because it is too large
Load diff
|
@ -66,22 +66,33 @@ impl Config {
|
|||
let mut file = try!(File::open(path));
|
||||
let mut data = String::new();
|
||||
try!(file.read_to_string(&mut data));
|
||||
serde_json::from_str(&data[..]).map_err(|_|
|
||||
Error::new(ErrorKind::InvalidInput, "Failed to decode configuration file.")
|
||||
)
|
||||
serde_json::from_str(&data[..]).map_err(|_| {
|
||||
Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Failed to decode configuration file.",
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Saves a JSON configuration to the desired path.
|
||||
pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<()> {
|
||||
let mut file = try!(File::create(path));
|
||||
file.write_all(try!(serde_json::to_string(self).map_err(|_|
|
||||
Error::new(ErrorKind::InvalidInput, "Failed to encode configuration file.")
|
||||
)).as_bytes())
|
||||
file.write_all(
|
||||
try!(serde_json::to_string(self).map_err(|_| {
|
||||
Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Failed to encode configuration file.",
|
||||
)
|
||||
})).as_bytes(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Determines whether or not the nickname provided is the owner of the bot.
|
||||
pub fn is_owner(&self, nickname: &str) -> bool {
|
||||
self.owners.as_ref().map(|o| o.contains(&nickname.to_owned())).unwrap()
|
||||
self.owners
|
||||
.as_ref()
|
||||
.map(|o| o.contains(&nickname.to_owned()))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Gets the nickname specified in the configuration.
|
||||
|
@ -99,7 +110,9 @@ impl Config {
|
|||
/// Gets the alternate nicknames specified in the configuration.
|
||||
/// This defaults to an empty vector when not specified.
|
||||
pub fn alternate_nicknames(&self) -> Vec<&str> {
|
||||
self.alt_nicks.as_ref().map_or(vec![], |v| v.iter().map(|s| &s[..]).collect())
|
||||
self.alt_nicks.as_ref().map_or(vec![], |v| {
|
||||
v.iter().map(|s| &s[..]).collect()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,13 +165,17 @@ impl Config {
|
|||
/// Gets the channels to join upon connection.
|
||||
/// This defaults to an empty vector if it's not specified.
|
||||
pub fn channels(&self) -> Vec<&str> {
|
||||
self.channels.as_ref().map_or(vec![], |v| v.iter().map(|s| &s[..]).collect())
|
||||
self.channels.as_ref().map_or(vec![], |v| {
|
||||
v.iter().map(|s| &s[..]).collect()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/// Gets the key for the specified channel if it exists in the configuration.
|
||||
pub fn channel_key(&self, chan: &str) -> Option<&str> {
|
||||
self.channel_keys.as_ref().and_then(|m| m.get(&chan.to_owned()).map(|s| &s[..]))
|
||||
self.channel_keys.as_ref().and_then(|m| {
|
||||
m.get(&chan.to_owned()).map(|s| &s[..])
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets the user modes to set on connect specified in the configuration.
|
||||
|
@ -182,7 +199,10 @@ impl Config {
|
|||
/// Gets the string to be sent in response to CTCP SOURCE requests.
|
||||
/// This defaults to `https://github.com/aatxe/irc` when not specified.
|
||||
pub fn source(&self) -> &str {
|
||||
self.source.as_ref().map_or("https://github.com/aatxe/irc", |s| &s[..])
|
||||
self.source.as_ref().map_or(
|
||||
"https://github.com/aatxe/irc",
|
||||
|s| &s[..],
|
||||
)
|
||||
}
|
||||
|
||||
/// Gets the amount of time in seconds since last activity necessary for the client to ping the
|
||||
|
@ -207,14 +227,19 @@ impl Config {
|
|||
/// Gets the NickServ command sequence to recover a nickname.
|
||||
/// This defaults to `["GHOST"]` when not specified.
|
||||
pub fn ghost_sequence(&self) -> Vec<&str> {
|
||||
self.ghost_sequence.as_ref().map_or(vec!["GHOST"], |v| v.iter().map(|s| &s[..]).collect())
|
||||
self.ghost_sequence.as_ref().map_or(vec!["GHOST"], |v| {
|
||||
v.iter().map(|s| &s[..]).collect()
|
||||
})
|
||||
}
|
||||
|
||||
/// Looks up the specified string in the options map.
|
||||
/// This uses indexing, and thus panics when the string is not present.
|
||||
/// This will also panic if used and there are no options.
|
||||
pub fn get_option(&self, option: &str) -> &str {
|
||||
self.options.as_ref().map(|o| &o[&option.to_owned()][..]).unwrap()
|
||||
self.options
|
||||
.as_ref()
|
||||
.map(|o| &o[&option.to_owned()][..])
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,7 +313,7 @@ mod test {
|
|||
fn is_owner() {
|
||||
let cfg = Config {
|
||||
owners: Some(vec![format!("test"), format!("test2")]),
|
||||
.. Default::default()
|
||||
..Default::default()
|
||||
};
|
||||
assert!(cfg.is_owner("test"));
|
||||
assert!(cfg.is_owner("test2"));
|
||||
|
@ -303,7 +328,7 @@ mod test {
|
|||
map.insert(format!("testing"), format!("test"));
|
||||
Some(map)
|
||||
},
|
||||
.. Default::default()
|
||||
..Default::default()
|
||||
};
|
||||
assert_eq!(cfg.get_option("testing"), "test");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Messages to and from the server.
|
||||
use std::borrow::ToOwned;
|
||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||
use std::io::{Result as IoResult};
|
||||
use std::io::Result as IoResult;
|
||||
use std::str::FromStr;
|
||||
use client::data::Command;
|
||||
|
||||
|
@ -18,14 +18,23 @@ pub struct Message {
|
|||
|
||||
impl Message {
|
||||
/// Creates a new Message.
|
||||
pub fn new(prefix: Option<&str>, command: &str, args: Vec<&str>, suffix: Option<&str>)
|
||||
-> IoResult<Message> {
|
||||
pub fn new(
|
||||
prefix: Option<&str>,
|
||||
command: &str,
|
||||
args: Vec<&str>,
|
||||
suffix: Option<&str>,
|
||||
) -> IoResult<Message> {
|
||||
Message::with_tags(None, prefix, command, args, suffix)
|
||||
}
|
||||
|
||||
/// Creates a new Message optionally including IRCv3.2 message tags.
|
||||
pub fn with_tags(tags: Option<Vec<Tag>>, prefix: Option<&str>, command: &str,
|
||||
args: Vec<&str>, suffix: Option<&str>) -> IoResult<Message> {
|
||||
pub fn with_tags(
|
||||
tags: Option<Vec<Tag>>,
|
||||
prefix: Option<&str>,
|
||||
command: &str,
|
||||
args: Vec<&str>,
|
||||
suffix: Option<&str>,
|
||||
) -> IoResult<Message> {
|
||||
Ok(Message {
|
||||
tags: tags,
|
||||
prefix: prefix.map(|s| s.to_owned()),
|
||||
|
@ -37,14 +46,16 @@ impl Message {
|
|||
pub fn source_nickname(&self) -> Option<&str> {
|
||||
// <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
|
||||
// <servername> ::= <host>
|
||||
self.prefix.as_ref().and_then(|s|
|
||||
match (s.find('!'), s.find('@'), s.find('.')) {
|
||||
(Some(i), _, _) => Some(&s[..i]), // <nick> '!' <user> [ '@' <host> ]
|
||||
(None, Some(i), _) => Some(&s[..i]), // <nick> '@' <host>
|
||||
(None, None, None) => Some(s), // <nick>
|
||||
_ => None // <servername>
|
||||
}
|
||||
)
|
||||
self.prefix.as_ref().and_then(|s| match (
|
||||
s.find('!'),
|
||||
s.find('@'),
|
||||
s.find('.'),
|
||||
) {
|
||||
(Some(i), _, _) => Some(&s[..i]), // <nick> '!' <user> [ '@' <host> ]
|
||||
(None, Some(i), _) => Some(&s[..i]), // <nick> '@' <host>
|
||||
(None, None, None) => Some(s), // <nick>
|
||||
_ => None, // <servername>
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts a Message into a String according to the IRC protocol.
|
||||
|
@ -65,7 +76,11 @@ impl Message {
|
|||
|
||||
impl From<Command> for Message {
|
||||
fn from(cmd: Command) -> Message {
|
||||
Message { tags: None, prefix: None, command: cmd }
|
||||
Message {
|
||||
tags: None,
|
||||
prefix: None,
|
||||
command: cmd,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,44 +88,52 @@ impl FromStr for Message {
|
|||
type Err = &'static str;
|
||||
fn from_str(s: &str) -> Result<Message, &'static str> {
|
||||
let mut state = s;
|
||||
if s.is_empty() { return Err("Cannot parse an empty string as a message.") }
|
||||
if s.is_empty() {
|
||||
return Err("Cannot parse an empty string as a message.");
|
||||
}
|
||||
let tags = if state.starts_with('@') {
|
||||
let tags = state.find(' ').map(|i| &state[1..i]);
|
||||
state = state.find(' ').map_or("", |i| &state[i+1..]);
|
||||
tags.map(|ts| ts.split(';').filter(|s| !s.is_empty()).map(|s: &str| {
|
||||
let mut iter = s.splitn(2, '=');
|
||||
let (fst, snd) = (iter.next(), iter.next());
|
||||
Tag(fst.unwrap_or("").to_owned(), snd.map(|s| s.to_owned()))
|
||||
}).collect::<Vec<_>>())
|
||||
state = state.find(' ').map_or("", |i| &state[i + 1..]);
|
||||
tags.map(|ts| {
|
||||
ts.split(';')
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s: &str| {
|
||||
let mut iter = s.splitn(2, '=');
|
||||
let (fst, snd) = (iter.next(), iter.next());
|
||||
Tag(fst.unwrap_or("").to_owned(), snd.map(|s| s.to_owned()))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let prefix = if state.starts_with(':') {
|
||||
let prefix = state.find(' ').map(|i| &state[1..i]);
|
||||
state = state.find(' ').map_or("", |i| &state[i+1..]);
|
||||
state = state.find(' ').map_or("", |i| &state[i + 1..]);
|
||||
prefix
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let suffix = if state.contains(" :") {
|
||||
let suffix = state.find(" :").map(|i| &state[i+2..state.len()-2]);
|
||||
state = state.find(" :").map_or("", |i| &state[..i+1]);
|
||||
let suffix = state.find(" :").map(|i| &state[i + 2..state.len() - 2]);
|
||||
state = state.find(" :").map_or("", |i| &state[..i + 1]);
|
||||
suffix
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let command = match state.find(' ').map(|i| &state[..i]) {
|
||||
Some(cmd) => {
|
||||
state = state.find(' ').map_or("", |i| &state[i+1..]);
|
||||
state = state.find(' ').map_or("", |i| &state[i + 1..]);
|
||||
cmd
|
||||
}
|
||||
_ => return Err("Cannot parse a message without a command.")
|
||||
_ => return Err("Cannot parse a message without a command."),
|
||||
};
|
||||
if suffix.is_none() { state = &state[..state.len() - 2] }
|
||||
if suffix.is_none() {
|
||||
state = &state[..state.len() - 2]
|
||||
}
|
||||
let args: Vec<_> = state.splitn(14, ' ').filter(|s| !s.is_empty()).collect();
|
||||
Message::with_tags(
|
||||
tags, prefix, command, args, suffix
|
||||
).map_err(|_| "Invalid input for Command.")
|
||||
Message::with_tags(tags, prefix, command, args, suffix)
|
||||
.map_err(|_| "Invalid input for Command.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,42 +165,69 @@ mod test {
|
|||
prefix: None,
|
||||
command: PRIVMSG(format!("test"), format!("Testing!")),
|
||||
};
|
||||
assert_eq!(Message::new(None, "PRIVMSG", vec!["test"], Some("Testing!")).unwrap(), message)
|
||||
assert_eq!(
|
||||
Message::new(None, "PRIVMSG", vec!["test"], Some("Testing!")).unwrap(),
|
||||
message
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn source_nickname() {
|
||||
assert_eq!(Message::new(
|
||||
None, "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), None);
|
||||
assert_eq!(
|
||||
Message::new(None, "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
None
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("irc.test.net"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), None);
|
||||
assert_eq!(
|
||||
Message::new(Some("irc.test.net"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
None
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("test!test@test"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), Some("test"));
|
||||
assert_eq!(
|
||||
Message::new(Some("test!test@test"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
Some("test")
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("test@test"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), Some("test"));
|
||||
assert_eq!(
|
||||
Message::new(Some("test@test"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
Some("test")
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("test!test@irc.test.com"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), Some("test"));
|
||||
assert_eq!(
|
||||
Message::new(Some("test!test@irc.test.com"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
Some("test")
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("test!test@127.0.0.1"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), Some("test"));
|
||||
assert_eq!(
|
||||
Message::new(Some("test!test@127.0.0.1"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
Some("test")
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("test@test.com"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), Some("test"));
|
||||
assert_eq!(
|
||||
Message::new(Some("test@test.com"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
Some("test")
|
||||
);
|
||||
|
||||
assert_eq!(Message::new(
|
||||
Some("test"), "PING", vec![], Some("data")
|
||||
).unwrap().source_nickname(), Some("test"));
|
||||
assert_eq!(
|
||||
Message::new(Some("test"), "PING", vec![], Some("data"))
|
||||
.unwrap()
|
||||
.source_nickname(),
|
||||
Some("test")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -193,7 +243,10 @@ mod test {
|
|||
prefix: Some(format!("test!test@test")),
|
||||
command: PRIVMSG(format!("test"), format!("Still testing!")),
|
||||
};
|
||||
assert_eq!(&message.to_string()[..], ":test!test@test PRIVMSG test :Still testing!\r\n");
|
||||
assert_eq!(
|
||||
&message.to_string()[..],
|
||||
":test!test@test PRIVMSG test :Still testing!\r\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -209,16 +262,25 @@ mod test {
|
|||
prefix: Some(format!("test!test@test")),
|
||||
command: PRIVMSG(format!("test"), format!("Still testing!")),
|
||||
};
|
||||
assert_eq!(":test!test@test PRIVMSG test :Still testing!\r\n".parse(), Ok(message));
|
||||
assert_eq!(
|
||||
":test!test@test PRIVMSG test :Still testing!\r\n".parse(),
|
||||
Ok(message)
|
||||
);
|
||||
let message = Message {
|
||||
tags: Some(vec![Tag(format!("aaa"), Some(format!("bbb"))),
|
||||
Tag(format!("ccc"), None),
|
||||
Tag(format!("example.com/ddd"), Some(format!("eee")))]),
|
||||
tags: Some(vec![
|
||||
Tag(format!("aaa"), Some(format!("bbb"))),
|
||||
Tag(format!("ccc"), None),
|
||||
Tag(format!("example.com/ddd"), Some(format!("eee"))),
|
||||
]),
|
||||
prefix: Some(format!("test!test@test")),
|
||||
command: PRIVMSG(format!("test"), format!("Testing with tags!")),
|
||||
};
|
||||
assert_eq!("@aaa=bbb;ccc;example.com/ddd=eee :test!test@test PRIVMSG test :Testing with \
|
||||
tags!\r\n".parse(), Ok(message))
|
||||
assert_eq!(
|
||||
"@aaa=bbb;ccc;example.com/ddd=eee :test!test@test PRIVMSG test :Testing with \
|
||||
tags!\r\n"
|
||||
.parse(),
|
||||
Ok(message)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -247,7 +309,9 @@ mod test {
|
|||
tags: None,
|
||||
prefix: Some(format!("test!test@test")),
|
||||
command: Raw(
|
||||
format!("COMMAND"), vec![format!("ARG:test")], Some(format!("Testing!"))
|
||||
format!("COMMAND"),
|
||||
vec![format!("ARG:test")],
|
||||
Some(format!("Testing!")),
|
||||
),
|
||||
};
|
||||
let msg: Message = ":test!test@test COMMAND ARG:test :Testing!\r\n".into();
|
||||
|
|
|
@ -13,11 +13,19 @@ pub mod kinds {
|
|||
|
||||
/// Trait describing all possible Writers for this library.
|
||||
pub trait IrcWrite: Write + Sized + Send + 'static {}
|
||||
impl<T> IrcWrite for T where T: Write + Sized + Send + 'static {}
|
||||
impl<T> IrcWrite for T
|
||||
where
|
||||
T: Write + Sized + Send + 'static,
|
||||
{
|
||||
}
|
||||
|
||||
/// Trait describing all possible Readers for this library.
|
||||
pub trait IrcRead: BufRead + Sized + Send + 'static {}
|
||||
impl<T> IrcRead for T where T: BufRead + Sized + Send + 'static {}
|
||||
impl<T> IrcRead for T
|
||||
where
|
||||
T: BufRead + Sized + Send + 'static,
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
pub mod caps;
|
||||
|
|
|
@ -369,7 +369,7 @@ impl FromStr for Response {
|
|||
if let Ok(rc) = s.parse() {
|
||||
match Response::from_u16(rc) {
|
||||
Some(r) => Ok(r),
|
||||
None => Err("Failed to parse due to unknown response code.")
|
||||
None => Err("Failed to parse due to unknown response code."),
|
||||
}
|
||||
} else {
|
||||
Err("Failed to parse response code.")
|
||||
|
|
|
@ -25,9 +25,9 @@ impl User {
|
|||
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..]);
|
||||
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());
|
||||
let hostname = state.find('@').map(|i| state[i + 1..].to_owned());
|
||||
User {
|
||||
nickname: nickname,
|
||||
username: username,
|
||||
|
@ -89,8 +89,8 @@ impl User {
|
|||
"-h" => self.sub_access_level(AccessLevel::HalfOp),
|
||||
"+v" => self.add_access_level(AccessLevel::Voice),
|
||||
"-v" => self.sub_access_level(AccessLevel::Voice),
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds an access level to the list, and updates the highest level if necessary.
|
||||
|
@ -123,7 +123,7 @@ impl User {
|
|||
impl PartialEq for User {
|
||||
fn eq(&self, other: &User) -> bool {
|
||||
self.nickname == other.nickname && self.username == other.username &&
|
||||
self.hostname == other.hostname
|
||||
self.hostname == other.hostname
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,9 @@ pub enum AccessLevel {
|
|||
|
||||
impl PartialOrd for AccessLevel {
|
||||
fn partial_cmp(&self, other: &AccessLevel) -> Option<Ordering> {
|
||||
if self == other { return Some(Equal) }
|
||||
if self == other {
|
||||
return Some(Equal);
|
||||
}
|
||||
match *self {
|
||||
AccessLevel::Owner => Some(Greater),
|
||||
AccessLevel::Admin => {
|
||||
|
@ -155,28 +157,28 @@ impl PartialOrd for AccessLevel {
|
|||
} else {
|
||||
Some(Greater)
|
||||
}
|
||||
},
|
||||
}
|
||||
AccessLevel::Oper => {
|
||||
if other == &AccessLevel::Owner || other == &AccessLevel::Admin {
|
||||
Some(Less)
|
||||
} else {
|
||||
Some(Greater)
|
||||
}
|
||||
},
|
||||
}
|
||||
AccessLevel::HalfOp => {
|
||||
if other == &AccessLevel::Voice || other == &AccessLevel::Member {
|
||||
Some(Greater)
|
||||
} else {
|
||||
Some(Less)
|
||||
}
|
||||
},
|
||||
}
|
||||
AccessLevel::Voice => {
|
||||
if other == &AccessLevel::Member {
|
||||
Some(Greater)
|
||||
} else {
|
||||
Some(Less)
|
||||
}
|
||||
},
|
||||
}
|
||||
AccessLevel::Member => Some(Less),
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +194,7 @@ impl FromStr for AccessLevel {
|
|||
Some('%') => Ok(AccessLevel::HalfOp),
|
||||
Some('+') => Ok(AccessLevel::Voice),
|
||||
None => Err("No access level in an empty string."),
|
||||
_ => Err("Failed to parse access level."),
|
||||
_ => Err("Failed to parse access level."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +260,7 @@ mod test {
|
|||
username: None,
|
||||
hostname: None,
|
||||
highest_access_level: Owner,
|
||||
access_levels: vec![Owner, Admin, Voice, Member]
|
||||
access_levels: vec![Owner, Admin, Voice, Member],
|
||||
};
|
||||
assert_eq!(user, exp);
|
||||
assert_eq!(user.highest_access_level, exp.highest_access_level);
|
||||
|
@ -324,7 +326,10 @@ mod test {
|
|||
fn derank_user_in_full() {
|
||||
let mut user = User::new("~&@%+user");
|
||||
assert_eq!(user.highest_access_level, Owner);
|
||||
assert_eq!(user.access_levels, vec![Owner, Admin, Oper, HalfOp, Voice, Member]);
|
||||
assert_eq!(
|
||||
user.access_levels,
|
||||
vec![Owner, Admin, Oper, HalfOp, Voice, Member]
|
||||
);
|
||||
user.update_access_level("-h");
|
||||
assert_eq!(user.highest_access_level, Owner);
|
||||
assert_eq!(user.access_levels, vec![Owner, Admin, Oper, Member, Voice]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue