diff --git a/src/lib.rs b/src/lib.rs index 18f0d55..06cae05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ use lazy_static::lazy_static; use regex::Regex; use std::io::{Error, Read, Write}; use std::net::TcpStream; -use std::time::Duration; +use std::borrow::Cow; lazy_static! { static ref PING_RE: Regex = Regex::new(r"^PING\s*:").unwrap(); @@ -11,6 +11,7 @@ lazy_static! { pub struct Client { stream: TcpStream, config: Config, + pub has_identified: bool, } pub struct Config { @@ -19,8 +20,16 @@ pub struct Config { mode: String, } +pub enum CapMode { + LS, + END +} + pub enum Command { PING(String), + CAP(CapMode), + USER(String, String, String, String), + NICK(String) } impl Command { @@ -41,7 +50,18 @@ impl Client { pub fn new(host: &str, port: u16, config: Config) -> Result { let stream = TcpStream::connect(format!("{}:{}", host, port))?; - Ok(Self { stream, config }) + Ok(Self { stream, config, has_identified: false }) + } + + pub fn try_identify(&mut self) -> Result<(), Error> { + if !self.has_identified { + self.write_command(Command::CAP(CapMode::LS))?; + self.write_command(Command::USER(self.config.username.clone(), "*".into(), "*".into(), self.config.username.clone()))?; + self.write_command(Command::NICK(self.config.nickname.clone()))?; + self.write_command(Command::CAP(CapMode::END))?; + } + + Ok(()) } // temporarily pub, change this later @@ -50,7 +70,11 @@ impl Client { match self.stream.read(&mut buffer) { Ok(_) => {} - Err(_) => return None, + Err(e) => { + println!("error occured {}", e); + + return None; + }, }; Some(String::from_utf8_lossy(&buffer).into()) @@ -64,12 +88,41 @@ impl Client { None // if it's none, there's no new messages } - pub fn write(&mut self, data: &str) -> Result<(), Error> { - self.stream.write_all(data.as_bytes())?; + fn write(&mut self, data: &str) -> Result<(), Error> { + let bytes = self.stream.write(data.as_bytes())?; + println!("Wrote {} bytes", bytes); // self.stream.flush()?; Ok(()) } + + pub fn write_command(&mut self, command: Command) -> Result<(), Error> { + use Command::*; + let computed = match command { + CAP(mode) => { + use CapMode::*; + Cow::Borrowed(match mode { + LS => "CAP LS 302", + END => "CAP END" + }) as Cow + }, + USER(username, s1, s2, realname) => { + let formatted = format!("USER {} {} {} :{}", username, s1, s2, realname); + + Cow::Owned(formatted) as Cow + }, + NICK(nickname) => { + let formatted = format!("NICK {}", nickname); + + Cow::Owned(formatted) as Cow + }, + _ => Cow::Borrowed("") as Cow + }; + + self.write(&computed)?; + + Ok(()) + } } impl Config { diff --git a/src/main.rs b/src/main.rs index f13f4f8..6b42d02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,14 +9,18 @@ macro_rules! loop_n { }}; } -fn main() { - let config = Config::new("test", None, Some("+B")); +fn main() -> Result<(), std::io::Error> { + let config = Config::new("test", Some("test"), Some("+B")); let mut client = Client::new("192.168.1.28", 6667, config).expect("Unable to connect to IRC server"); loop { + client.try_identify()?; + // client.has_identified = true; if let Some(line) = client.read_string() { print!("{}", line); } } + + Ok(()) }