use chrono::{DateTime, Utc}; use stanza::{client::presence::String1024, xep_0203::Delay}; use crate::caps; #[derive(Debug, Default, Clone)] pub struct Online { pub show: Option, pub status: Option, pub priority: Option, } #[derive(Debug, Clone, Copy)] pub enum Show { Away, Chat, DoNotDisturb, ExtendedAway, } #[derive(Debug, Default, Clone)] pub struct Offline { pub status: Option, } #[derive(Debug, Clone)] pub enum PresenceType { Online(Online), Offline(Offline), } #[derive(Debug, Clone)] pub struct Presence { pub timestamp: DateTime, pub presence: PresenceType, } impl Online { pub fn into_stanza( self, timestamp: Option>, ) -> stanza::client::presence::Presence { stanza::client::presence::Presence { show: self.show.map(|show| match show { Show::Away => stanza::client::presence::Show::Away, Show::Chat => stanza::client::presence::Show::Chat, Show::DoNotDisturb => stanza::client::presence::Show::Dnd, Show::ExtendedAway => stanza::client::presence::Show::Xa, }), // TODO: enforce message length in status message status: self.status.map(|status| stanza::client::presence::Status { lang: None, status: String1024(status), }), priority: self .priority .map(|priority| stanza::client::presence::Priority(priority)), delay: timestamp.map(|timestamp| Delay { from: None, stamp: timestamp, }), c: Some(caps::c()), ..Default::default() } } } impl Offline { pub fn into_stanza( self, timestamp: Option>, ) -> stanza::client::presence::Presence { stanza::client::presence::Presence { r#type: Some(stanza::client::presence::PresenceType::Unavailable), status: self.status.map(|status| stanza::client::presence::Status { lang: None, status: String1024(status), }), delay: timestamp.map(|timestamp| Delay { from: None, stamp: timestamp, }), c: Some(caps::c()), ..Default::default() } } } impl From for stanza::client::presence::Presence { fn from(value: PresenceType) -> Self { match value { PresenceType::Online(online) => online.into_stanza(None), PresenceType::Offline(offline) => offline.into_stanza(None), } } } impl From for stanza::client::presence::Presence { fn from(value: Presence) -> Self { match value.presence { PresenceType::Online(online) => online.into_stanza(Some(value.timestamp)), PresenceType::Offline(offline) => offline.into_stanza(Some(value.timestamp)), } } }