diff options
Diffstat (limited to '')
| -rw-r--r-- | luz/.gitignore | 1 | ||||
| -rw-r--r-- | luz/src/lib.rs | 22 | ||||
| -rw-r--r-- | luz/src/main.rs | 10 | ||||
| -rw-r--r-- | luz/src/presence.rs | 19 | 
4 files changed, 41 insertions, 11 deletions
| diff --git a/luz/.gitignore b/luz/.gitignore index 1a2cec2..60868fd 100644 --- a/luz/.gitignore +++ b/luz/.gitignore @@ -1 +1,2 @@  luz.db +.sqlx/ diff --git a/luz/src/lib.rs b/luz/src/lib.rs index 4c95ab6..293bc08 100644 --- a/luz/src/lib.rs +++ b/luz/src/lib.rs @@ -8,6 +8,7 @@ use chat::{Body, Chat, Message};  use connection::{write::WriteMessage, SupervisorSender};  use db::Db;  use error::{ConnectionError, Reason, RosterError, StatusError}; +use futures::{future::Fuse, FutureExt};  use jabber::JID;  use presence::{Offline, Online, Presence};  use roster::{Contact, ContactUpdate}; @@ -47,7 +48,7 @@ pub struct Luz {      db: Db,      sender: mpsc::Sender<UpdateMessage>,      /// if connection was shut down due to e.g. server shutdown, supervisor must be able to mark client as disconnected -    connection_supervisor_shutdown: oneshot::Receiver<()>, +    connection_supervisor_shutdown: Fuse<oneshot::Receiver<()>>,      // TODO: will need to have an auto reconnect state as well (e.g. in case server shut down, to try and reconnect later)      // TODO: will grow forever at this point, maybe not required as tasks will naturally shut down anyway?      tasks: JoinSet<()>, @@ -60,7 +61,7 @@ impl Luz {          jid: Arc<Mutex<JID>>,          password: String,          connected: Arc<Mutex<Option<(WriteHandle, SupervisorHandle)>>>, -        connection_supervisor_shutdown: oneshot::Receiver<()>, +        connection_supervisor_shutdown: Fuse<oneshot::Receiver<()>>,          db: SqlitePool,          sender: mpsc::Sender<UpdateMessage>,      ) -> Self { @@ -82,9 +83,8 @@ impl Luz {          loop {              let msg = tokio::select! {                  // this is okay, as when created the supervisor (and connection) doesn't exist, but a bit messy -                // THIS IS NOT OKAY LOLLLL +                // THIS IS NOT OKAY LOLLLL - apparently fusing is the best option???                  _ = &mut self.connection_supervisor_shutdown => { -                    info!("got this");                      *self.connected.lock().await = None;                      continue;                  } @@ -130,6 +130,7 @@ impl Luz {                                          self.password.clone(),                                          self.pending_iqs.clone(),                                      ); +                                    let shutdown_recv = shutdown_recv.fuse();                                      self.connection_supervisor_shutdown = shutdown_recv;                                      // TODO: get roster and send initial presence                                      let (send, recv) = oneshot::channel(); @@ -237,7 +238,7 @@ impl Luz {                          }                      };                  } -                CommandMessage::Disconnect(_offline) => { +                CommandMessage::Disconnect(offline) => {                      match self.connected.lock().await.as_mut() {                          None => {                              let _ = self @@ -247,15 +248,19 @@ impl Luz {                          }                          mut c => {                              // TODO: send unavailable presence -                            if let Some((_write_handle, supervisor_handle)) = c.take() { +                            if let Some((write_handle, supervisor_handle)) = c.take() { +                                let offline_presence: stanza::client::presence::Presence = +                                    offline.clone().into(); +                                let stanza = Stanza::Presence(offline_presence); +                                // TODO: timeout and error check +                                write_handle.write(stanza).await;                                  let _ = supervisor_handle.send(SupervisorCommand::Disconnect).await; -                                c = None; +                                let _ = self.sender.send(UpdateMessage::Offline(offline)).await;                              } else {                                  unreachable!()                              };                          }                      } -                    info!("lock released")                  }                  _ => {                      match self.connected.lock().await.as_ref() { @@ -1004,6 +1009,7 @@ impl LuzHandle {          let (update_sender, update_receiver) = mpsc::channel(20);          // might be bad, first supervisor shutdown notification oneshot is never used (disgusting)          let (sup_send, sup_recv) = oneshot::channel(); +        let mut sup_recv = sup_recv.fuse();          let actor = Luz::new(              command_sender.clone(), diff --git a/luz/src/main.rs b/luz/src/main.rs index 9779351..2506883 100644 --- a/luz/src/main.rs +++ b/luz/src/main.rs @@ -12,9 +12,13 @@ use tracing::info;  #[tokio::main]  async fn main() {      tracing_subscriber::fmt::init(); -    let db = SqlitePool::connect("./luz.db").await.unwrap(); -    let (luz, mut recv) = -        LuzHandle::new("test@blos.sm".try_into().unwrap(), "slayed".to_string(), db); +    let (luz, mut recv) = LuzHandle::new( +        "test@blos.sm".try_into().unwrap(), +        "slayed".to_string(), +        "./luz.db", +    ) +    .await +    .unwrap();      tokio::spawn(async move {          while let Some(msg) = recv.recv().await { diff --git a/luz/src/presence.rs b/luz/src/presence.rs index 40d79c5..31a0d30 100644 --- a/luz/src/presence.rs +++ b/luz/src/presence.rs @@ -91,3 +91,22 @@ impl From<Online> for stanza::client::presence::Presence {          }      }  } + +impl From<Offline> for stanza::client::presence::Presence { +    fn from(value: Offline) -> Self { +        Self { +            from: None, +            id: None, +            to: None, +            r#type: Some(stanza::client::presence::PresenceType::Unavailable), +            lang: None, +            show: None, +            status: value.status.map(|status| stanza::client::presence::Status { +                lang: None, +                status: String1024(status), +            }), +            priority: None, +            errors: Vec::new(), +        } +    } +} | 
