Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use crate::IrcClientInformation;
- use irc_core::MsgTo::User;
- use irc_core::{entities, Message, Reply, UserMode};
- use std::sync::mpsc::Receiver;
- use std::sync::Mutex;
- use std::time::Duration;
- use std::{
- io::{Read, Write},
- net::{TcpStream, ToSocketAddrs},
- sync::{mpsc::channel, Arc},
- thread,
- };
- pub struct IrcClient {
- client: TcpStream,
- hooks: Arc<Mutex<Vec<Box<dyn IrcClientEvent + Sync + Send>>>>,
- }
- pub trait IrcClientEvent {
- fn on_message_received(&self, _message: &str) {}
- }
- impl IrcClient {
- pub fn connect<T: ToSocketAddrs>(addr: T) -> std::io::Result<Self> {
- let client_res = TcpStream::connect(addr);
- if let Ok(client) = client_res {
- return Ok(Self {
- client,
- hooks: Arc::new(Mutex::new(Vec::new())),
- });
- }
- Err(client_res.unwrap_err())
- }
- pub fn add_hook<E: IrcClientEvent + Sync + Send + 'static>(&mut self, hook: E) {
- self.hooks.lock().unwrap().push(Box::new(hook));
- }
- pub fn start(&mut self, client_information: IrcClientInformation, mode: UserMode) {
- let (tx, rx) = channel::<Reply>();
- let mut client = self
- .client
- .try_clone()
- .expect("Error creating TcpStream clone for listener thread");
- let hooks = self.hooks.clone();
- thread::spawn(move || {
- let mut buffer = [0_u8; 4096];
- loop {
- let bytes_read = client.read(&mut buffer).unwrap();
- let mut raw_messages = std::str::from_utf8(&buffer[..bytes_read]).unwrap();
- let message_strings: Vec<&str> = raw_messages.split("\r\n").collect();
- for msg_str in message_strings {
- if msg_str.starts_with("RPL") || msg_str.starts_with("ERR") {
- tx.send(Reply::None(msg_str.to_string())).unwrap()
- } else {
- let lock = hooks.lock().unwrap();
- for hook in &*lock {
- hook.on_message_received(msg_str)
- }
- }
- }
- }
- });
- thread::sleep(Duration::new(1, 0));
- let user = entities::User {
- nickname: client_information.nickname,
- username: client_information.username,
- realname: client_information.realname,
- };
- Self::write_message(&mut self.client, Message::nick(user.clone()));
- Self::write_message(&mut self.client, Message::user(user, mode));
- }
- fn write_message(client: &mut TcpStream, message: Message) {
- client
- .write(message.into_bytes().as_ref())
- .expect("Error sending message to server");
- }
- fn await_message_response(
- client: &mut TcpStream,
- rx: &Receiver<Reply>,
- message: Message,
- ) -> Reply {
- Self::write_message(client, message);
- rx.recv_timeout(Duration::new(0, 2000))
- .expect("Timeout waiting for reply")
- }
- fn read_message(client: &mut TcpStream, buffer: &mut [u8]) -> usize {
- client
- .read(buffer)
- .expect("Error reading response message from server")
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement