1use super::event_handler::EventHandler;
2use super::event_manager;
3use super::message_parser;
4use std::error::Error;
5use std::sync::Arc;
6use tokio::io::BufReader;
7use tokio::net::TcpStream;
8use tokio::prelude::*;
9use tokio::sync::Mutex;
10#[derive(Clone)]
13pub enum ClientState {
14 Uninit,
15 Connecting,
16 Registering,
17 InServer, InChannel(String),
19}
20
21pub struct Client {
22 ip: String,
23 port: u16,
24 event_handler: Option<Arc<dyn EventHandler>>,
25 pub state: ClientState,
26 pub stream: Option<Arc<Mutex<IrcStream<TcpStream>>>>,
27}
28
29impl Client {
30 pub fn new(ip: &str, port: u16) -> Client {
31 Client {
32 ip: ip.to_string(),
33 port,
34 event_handler: None,
35 state: ClientState::Uninit,
36 stream: None,
37 }
38 }
39
40 pub fn handler<H: EventHandler + 'static>(mut self, event_handler: H) -> Self {
41 self.event_handler = Some(Arc::new(event_handler));
42 self
43 }
44
45 pub async fn connect(mut self) -> Result<Self, Box<dyn Error>> {
46 self.stream = Some(Arc::new(Mutex::new(
47 IrcStream::connect(&self.ip, self.port).await?,
48 )));
49 self.state = ClientState::Connecting;
50 Ok(self)
51 }
52
53 pub async fn start(&mut self) -> Result<(), Box<dyn Error>> {
54 let event_handler = self.event_handler.take().unwrap();
55
56 loop {
57 let stream = Arc::clone(&self.stream.as_ref().unwrap());
58 let mut s = stream.try_lock().unwrap();
59 let message = s.consume_message().await.unwrap();
60 std::mem::drop(s); let message = message_parser::parse_message(&message.0).unwrap();
63 if let Err(e) = event_manager::handle_event(self, message, &event_handler).await {
64 eprintln!("Error: {}", e);
65 break;
66 }
67 }
68
69 Ok(())
70 }
71
72 pub async fn register(&mut self, username: &str) -> Result<(), Box<dyn Error>> {
73 send_socket_message(self, &format!("PASS {}", username)).await?;
74 send_socket_message(self, &format!("NICK {}", username)).await?;
75 send_socket_message(self, &format!("USER guest * 0 :{}", username)).await?;
76 Ok(())
77 }
78 pub async fn join_channel(&mut self, name: &str) -> Result<(), Box<dyn Error>> {
79 send_socket_message(self, &format!("JOIN #{}", name)).await?;
80 Ok(())
81 }
82
83 pub async fn send_message(&mut self, msg: String) -> Result<(), Box<dyn Error>> {
84 match self.state.clone() {
85 ClientState::InChannel(name) => {
86 send_socket_message(self, &format!("PRIVMSG #{} {}", &name, msg)).await?;
87 },
88 _ => {
89 panic!("Can't send a message when not in channel!");
90 }
91 }
92 Ok(())
93 }
94
95 pub async fn send_pong(&mut self) -> Result<(), Box<dyn Error>> {
96 send_socket_message(self, "PONG").await?;
97 Ok(())
98 }
99}
100
101pub struct IrcStream<S> {
102 reader: BufReader<S>,
103}
104
105impl IrcStream<TcpStream> {
106 pub async fn connect(peer: &str, port: u16) -> Result<Self, Box<dyn Error>> {
107 let connection = TcpStream::connect(&format!("{}:{}", peer, port)).await?;
108 Ok(IrcStream::new(connection))
109 }
110}
111
112impl<S: AsyncRead + AsyncWrite + Unpin> IrcStream<S> {
113 pub fn new(stream: S) -> Self {
114 IrcStream {
115 reader: BufReader::new(stream),
116 }
117 }
118
119 pub async fn consume_message(&mut self) -> Result<(Vec<u8>, usize), Box<dyn Error>> {
120 let mut buf = Vec::new();
121 let test = self.reader.read_until(b'\n', &mut buf).await?;
122 Ok((buf, test))
123 }
124
125 pub async fn write_all(&mut self, test: &str) -> Result<(), Box<dyn Error>> {
126 self.reader
127 .write(&format!("{}\r\n", test)[..].as_bytes())
128 .await?;
129 Ok(())
130 }
131}
132
133pub async fn send_socket_message(client: &mut Client, msg: &str) -> Result<(), Box<dyn Error>> {
134 let stream = Arc::clone(client.stream.as_ref().unwrap());
135 let mut s = stream.try_lock().unwrap();
136
137 s.write_all(msg).await?;
138 Ok(())
139}