xmpp-rs/tokio-xmpp/src/event.rs

156 lines
3.7 KiB
Rust
Raw Normal View History

use rand::{thread_rng, Rng};
use xmpp_parsers::{iq::Iq, jid::Jid, message::Message, presence::Presence};
use crate::xmlstream::XmppStreamElement;
use crate::Error;
fn make_id() -> String {
let id: u64 = thread_rng().gen();
format!("{}", id)
}
/// A stanza sent/received over the stream.
#[derive(Debug)]
pub enum Stanza {
/// IQ stanza
Iq(Iq),
/// Message stanza
Message(Message),
/// Presence stanza
Presence(Presence),
}
impl Stanza {
/// Assign a random ID to the stanza, if no ID has been assigned yet.
pub fn ensure_id(&mut self) -> &str {
match self {
Self::Iq(iq) => {
if iq.id.len() == 0 {
iq.id = make_id();
}
&iq.id
}
Self::Message(message) => message.id.get_or_insert_with(make_id),
Self::Presence(presence) => presence.id.get_or_insert_with(make_id),
}
}
}
impl From<Iq> for Stanza {
fn from(other: Iq) -> Self {
Self::Iq(other)
}
}
impl From<Presence> for Stanza {
fn from(other: Presence) -> Self {
Self::Presence(other)
}
}
impl From<Message> for Stanza {
fn from(other: Message) -> Self {
Self::Message(other)
}
}
impl TryFrom<Stanza> for Message {
type Error = Stanza;
fn try_from(other: Stanza) -> Result<Self, Self::Error> {
match other {
Stanza::Message(st) => Ok(st),
other => Err(other),
}
}
}
impl TryFrom<Stanza> for Presence {
type Error = Stanza;
fn try_from(other: Stanza) -> Result<Self, Self::Error> {
match other {
Stanza::Presence(st) => Ok(st),
other => Err(other),
}
}
}
impl TryFrom<Stanza> for Iq {
type Error = Stanza;
fn try_from(other: Stanza) -> Result<Self, Self::Error> {
match other {
Stanza::Iq(st) => Ok(st),
other => Err(other),
}
}
}
impl From<Stanza> for XmppStreamElement {
fn from(other: Stanza) -> Self {
match other {
Stanza::Iq(st) => Self::Iq(st),
Stanza::Message(st) => Self::Message(st),
Stanza::Presence(st) => Self::Presence(st),
}
}
}
2017-07-13 01:47:05 +02:00
2018-08-02 19:58:19 +02:00
/// High-level event on the Stream implemented by Client and Component
2017-07-13 01:47:05 +02:00
#[derive(Debug)]
pub enum Event {
2018-08-02 19:58:19 +02:00
/// Stream is connected and initialized
Online {
/// Server-set Jabber-Id for your session
///
/// This may turn out to be a different JID resource than
/// expected, so use this one instead of the JID with which
/// the connection was setup.
bound_jid: Jid,
/// Was this session resumed?
///
/// Not yet implemented for the Client
resumed: bool,
},
2018-08-02 19:58:19 +02:00
/// Stream end
2020-03-05 01:25:24 +01:00
Disconnected(Error),
2018-08-02 19:58:19 +02:00
/// Received stanza/nonza
Stanza(Stanza),
2017-07-13 01:47:05 +02:00
}
impl Event {
2018-08-02 19:58:19 +02:00
/// `Online` event?
2017-07-13 01:47:05 +02:00
pub fn is_online(&self) -> bool {
2017-07-21 00:19:08 +02:00
match *self {
Event::Online { .. } => true,
2017-07-13 01:47:05 +02:00
_ => false,
}
}
/// Get the server-assigned JID for the `Online` event
pub fn get_jid(&self) -> Option<&Jid> {
match *self {
Event::Online { ref bound_jid, .. } => Some(bound_jid),
_ => None,
}
}
2018-08-02 19:58:19 +02:00
/// If this is a `Stanza` event, get its data
pub fn as_stanza(&self) -> Option<&Stanza> {
2017-07-21 00:19:08 +02:00
match *self {
Event::Stanza(ref stanza) => Some(stanza),
2017-07-13 01:47:05 +02:00
_ => None,
}
}
2018-08-02 19:58:19 +02:00
/// If this is a `Stanza` event, unwrap into its data
pub fn into_stanza(self) -> Option<Stanza> {
match self {
Event::Stanza(stanza) => Some(stanza),
_ => None,
}
}
2017-07-13 01:47:05 +02:00
}