Ran rustfmt on all the code.

This commit is contained in:
Aaron Weiss 2017-06-19 13:59:26 -04:00
parent 388628d62a
commit f0f0b95038
No known key found for this signature in database
GPG key ID: 0237035D9BF03AE2
15 changed files with 1953 additions and 1178 deletions

File diff suppressed because it is too large Load diff

View file

@ -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");
}

View file

@ -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();

View file

@ -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;

View file

@ -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.")

View file

@ -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]);