plankircd/src/context.rs

78 lines
2.4 KiB
Rust

use futures::sync::mpsc::UnboundedSender;
use futures::sync::mpsc::SendError;
use std::net::SocketAddr;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use user::User;
use channel::Channel;
use models::IrcMessage;
use models::IrcCommand;
#[derive(Clone)]
pub struct Context {
pub hostname: Arc<Mutex<String>>,
pub users: Arc<Mutex<HashMap<SocketAddr,User>>>,
pub channels: Arc<Mutex<HashMap<String,Channel>>>,
}
impl Context {
pub fn new() -> Context {
Context {
hostname: Arc::new(Mutex::new("plankircd".to_string())),
users: Arc::new(Mutex::new(HashMap::new())),
channels: Arc::new(Mutex::new(HashMap::new())),
}
}
pub fn register_user(&mut self, addr: &SocketAddr) -> Result<(), ()> {
let mut users = self.users.lock().unwrap();
let cloned = {
users.get(addr).cloned()
};
match cloned {
Some(cloned) => {
if !cloned.is_valid() || cloned.is_registered() {
return Err(());
}
if users.iter().any(|(k, v)| k != addr && v.nickname == cloned.nickname) {
return Err(());
}
users.get_mut(addr).unwrap().register();
Ok(())
},
None => Err(())
}
}
pub fn nick_exists(&self, nick: &str) -> bool {
self.users.lock().unwrap().values().any(|user| user.nickname == nick)
}
pub fn send_message_to(&self, addr: &SocketAddr, msg: IrcMessage) -> Result<(), SendError<String>> {
if let Some(user) = self.users.lock().unwrap().get(addr) {
user.send(msg)
}
else { Ok(()) }
}
pub fn is_registered(&self, addr: &SocketAddr) -> bool {
if let Some(user) = self.users.lock().unwrap().get(addr) {
user.is_registered()
}
else {
false
}
}
pub fn connect(&mut self, addr: SocketAddr, send: UnboundedSender<String>) {
self.users.lock().unwrap().insert(addr, User::new(send));
}
pub fn disconnect(&mut self, addr: &SocketAddr) {
if let Some(user) = self.users.lock().unwrap().remove(addr) {
user.send(IrcMessage::new(Some(&self.hostname.lock().unwrap()), IrcCommand::ERROR, vec!["Connection terminated."]));
}
}
}