From abc3ffa7363ebd30101e15db7e02a7d44f323df9 Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Fri, 16 Jun 2023 17:13:01 +0100 Subject: refactor jabber client --- src/lib.rs | 106 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 23 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 42eb7de..10c7172 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,36 +5,37 @@ use std::{ str::FromStr, }; -use tokio::net::TcpStream; +use jid::JID; +use quick_xml::{Reader, Writer}; +use tokio::net::{ + tcp::{OwnedReadHalf, OwnedWriteHalf}, + TcpStream, +}; -mod jid; +pub mod jid; -pub struct Jabber { - connection: Option, - login: jid::JID, +pub struct JabberData { + jid: jid::JID, password: String, } -impl Jabber { - fn new(login: jid::JID, password: String) -> Self { - Self { - connection: None, - login, - password, - } +impl JabberData { + pub fn new(jid: JID, password: String) -> Self { + Self { jid, password } } - async fn resolve_client(&self) -> Vec { + + async fn get_sockets(&self) -> Vec { let mut socket_addrs = Vec::new(); // if it's a socket/ip then just return that // socket - if let Ok(socket_addr) = SocketAddr::from_str(&self.login.domainpart) { + if let Ok(socket_addr) = SocketAddr::from_str(&self.jid.domainpart) { socket_addrs.push(socket_addr); return socket_addrs; } // ip - if let Ok(ip) = IpAddr::from_str(&self.login.domainpart) { + if let Ok(ip) = IpAddr::from_str(&self.jid.domainpart) { socket_addrs.push(SocketAddr::new(ip, 5222)); socket_addrs.push(SocketAddr::new(ip, 5223)); return socket_addrs; @@ -45,7 +46,7 @@ impl Jabber { // otherwise resolve if let Ok(resolver) = trust_dns_resolver::AsyncResolver::tokio_from_system_conf() { if let Ok(lookup) = resolver - .srv_lookup(format!("_xmpp-client._tcp.{}", self.login.domainpart)) + .srv_lookup(format!("_xmpp-client._tcp.{}", self.jid.domainpart)) .await { for srv in lookup { @@ -60,7 +61,7 @@ impl Jabber { } } if let Ok(lookup) = resolver - .srv_lookup(format!("_xmpps-client._tcp.{}", self.login.domainpart)) + .srv_lookup(format!("_xmpps-client._tcp.{}", self.jid.domainpart)) .await { for srv in lookup { @@ -76,7 +77,7 @@ impl Jabber { } // in case cannot connect through SRV records - resolver.lookup_ip(&self.login.domainpart).await.map(|ips| { + resolver.lookup_ip(&self.jid.domainpart).await.map(|ips| { for ip in ips { socket_addrs.push(SocketAddr::new(ip, 5222)); socket_addrs.push(SocketAddr::new(ip, 5223)); @@ -86,18 +87,67 @@ impl Jabber { socket_addrs } +} + +pub struct Jabber { + reader: Reader, + writer: Writer, + data: JabberData, +} + +#[derive(Debug)] +pub enum JabberError { + NotConnected, +} - async fn connect(&mut self) { - for socket_addr in self.resolve_client().await { +impl Jabber { + pub async fn connect(data: JabberData) -> Result { + for socket_addr in data.get_sockets().await { println!("trying {}", socket_addr); if let Ok(stream) = TcpStream::connect(socket_addr).await { println!("connected to {}", socket_addr); - self.connection = Some(stream); + let (read, write) = stream.into_split(); + return Ok(Self { + reader: Reader::from_reader(read), + writer: Writer::new(write), + data, + }); + } + } + Err(JabberError::NotConnected) + } + + async fn reconnect(&mut self) { + for socket_addr in self.data.get_sockets().await { + println!("trying {}", socket_addr); + if let Ok(stream) = TcpStream::connect(socket_addr).await { + println!("connected to {}", socket_addr); + let (read, write) = stream.into_split(); + self.reader = Reader::from_reader(read); + self.writer = Writer::new(write); return; } } println!("could not connect") } + + async fn begin_stream(&mut self) -> Result<(), JabberError> { + todo!() + } + + async fn starttls() -> Result<(), JabberError> { + todo!() + } + + async fn directtls() -> Result<(), JabberError> { + todo!() + } + + async fn auth(&mut self) -> Result<(), JabberError> { + todo!() + } + + async fn close(&mut self) {} } #[cfg(test)] @@ -108,7 +158,17 @@ mod tests { #[tokio::test] async fn get_sockets() { - let client = Jabber::new(JID::from_str("cel@blos.sm").unwrap(), "password".to_owned()); - println!("{:?}", client.resolve_client().await) + let data = JabberData::new(JID::from_str("cel@blos.sm").unwrap(), "password".to_owned()); + println!("{:?}", data.get_sockets().await) + } + + #[tokio::test] + async fn connect() { + Jabber::connect(JabberData::new( + JID::from_str("cel@blos.sm").unwrap(), + "password".to_owned(), + )) + .await + .unwrap(); } } -- cgit