Changed Server API to provide channel lists, and fixed channel tracking

to work with user PARTs.
This commit is contained in:
Aaron Weiss 2017-05-25 17:25:43 +02:00
parent 4446b8e875
commit 38c7ed2c71
No known key found for this signature in database
GPG key ID: 0237035D9BF03AE2

View file

@ -27,6 +27,9 @@ pub trait Server {
/// Gets an iterator over received messages.
fn iter<'a>(&'a self) -> Box<Iterator<Item = Result<Message>> + 'a>;
/// Gets a list of currently joined channels. This will be none if tracking is not supported altogether.
fn list_channels(&self) -> Option<Vec<String>>;
/// Gets a list of Users in the specified channel. This will be none if the channel is not
/// being tracked, or if tracking is not supported altogether. For best results, be sure to
/// request `multi-prefix` support from the server.
@ -196,12 +199,21 @@ impl<'a> Server for ServerState {
panic!("unimplemented")
}
#[cfg(not(feature = "nochanlists"))]
fn list_channels(&self) -> Option<Vec<String>> {
Some(self.chanlists.lock().unwrap().keys().map(|k| k.to_owned()).collect())
}
#[cfg(feature = "nochanlists")]
fn list_channels(&self) -> Option<Vec<String>> {
None
}
#[cfg(not(feature = "nochanlists"))]
fn list_users(&self, chan: &str) -> Option<Vec<User>> {
self.chanlists.lock().unwrap().get(&chan.to_owned()).cloned()
}
#[cfg(feature = "nochanlists")]
fn list_users(&self, _: &str) -> Option<Vec<User>> {
None
@ -214,6 +226,8 @@ impl Server for IrcServer {
}
fn send<M: Into<Message>>(&self, msg: M) -> Result<()> where Self: Sized {
let msg = msg.into();
try!(self.handle_sent_message(&msg));
self.state.send(msg)
}
@ -221,12 +235,21 @@ impl Server for IrcServer {
Box::new(ServerIterator::new(self))
}
#[cfg(not(feature = "nochanlists"))]
fn list_channels(&self) -> Option<Vec<String>> {
Some(self.state.chanlists.lock().unwrap().keys().map(|k| k.to_owned()).collect())
}
#[cfg(feature = "nochanlists")]
fn list_channels(&self) -> Option<Vec<String>> {
None
}
#[cfg(not(feature = "nochanlists"))]
fn list_users(&self, chan: &str) -> Option<Vec<User>> {
self.state.chanlists.lock().unwrap().get(&chan.to_owned()).cloned()
}
#[cfg(feature = "nochanlists")]
fn list_users(&self, _: &str) -> Option<Vec<User>> {
None
@ -327,7 +350,18 @@ impl IrcServer {
&self.state.chanlists
}
/// Handles messages internally for basic client functionality.
/// Handles sent messages internally for basic client functionality.
fn handle_sent_message(&self, msg: &Message) -> Result<()> {
match msg.command {
PART(ref chan, _) => {
let _ = self.state.chanlists.lock().unwrap().remove(chan);
},
_ => ()
}
Ok(())
}
/// Handles received messages internally for basic client functionality.
fn handle_message(&self, msg: &Message) -> Result<()> {
match msg.command {
PING(ref data, _) => try!(self.send_pong(&data)),
@ -440,6 +474,7 @@ impl IrcServer {
}
}
}
#[cfg(feature = "nochanlists")]
fn handle_nick_change(&self, _: &str, _: &str) {}
@ -456,7 +491,6 @@ impl IrcServer {
}
}
}
#[cfg(feature = "nochanlists")]
fn handle_mode(&self, chan: &str, mode: &str, user: &str) {}
@ -587,7 +621,7 @@ mod test {
use client::conn::MockConnection;
use client::data::Config;
#[cfg(not(feature = "nochanlists"))] use client::data::User;
use client::data::command::Command::PRIVMSG;
use client::data::command::Command::{PART, PRIVMSG};
pub fn test_config() -> Config {
Config {
@ -759,6 +793,29 @@ mod test {
assert_eq!(&get_server_value(server)[..], "PRIVMSG #test :Hi there!\n");
}
#[test]
#[cfg(not(feature = "nochanlists"))]
fn channel_tracking_names() {
let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n";
let server = IrcServer::from_connection(test_config(), MockConnection::new(value));
for message in server.iter() {
println!("{:?}", message);
}
assert_eq!(server.list_channels().unwrap(), vec!["#test".to_owned()])
}
#[test]
#[cfg(not(feature = "nochanlists"))]
fn channel_tracking_names_part() {
let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n";
let server = IrcServer::from_connection(test_config(), MockConnection::new(value));
for message in server.iter() {
println!("{:?}", message);
}
assert!(server.send(PART(format!("#test"), None)).is_ok());
assert!(server.list_channels().unwrap().is_empty())
}
#[test]
#[cfg(not(feature = "nochanlists"))]
fn user_tracking_names() {