Skip to main content

tokio_xmpp/
event.rs

1// Copyright (c) 2024 Jonas Schäfer <jonas@zombofant.net>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use xmpp_parsers::{jid::Jid, message::Id, stanza::Stanza, stream_features::StreamFeatures};
8
9use crate::xmlstream::XmppStreamElement;
10use crate::Error;
11
12pub(crate) fn make_id() -> String {
13    let id: u64 = rand::random();
14    format!("{}", id)
15}
16
17/// Assign a random ID to the stanza, if no ID has been assigned yet.
18pub fn ensure_stanza_id(stanza: &mut Stanza) -> &str {
19    match stanza {
20        Stanza::Iq(iq) => {
21            let id = iq.id_mut();
22            if id.is_empty() {
23                *id = make_id();
24            }
25            id
26        }
27        Stanza::Message(message) => message.id.get_or_insert_with(|| Id(make_id())).0.as_ref(),
28        Stanza::Presence(presence) => presence.id.get_or_insert_with(make_id),
29    }
30}
31
32impl From<Stanza> for XmppStreamElement {
33    fn from(other: Stanza) -> Self {
34        Self::Stanza(other)
35    }
36}
37
38/// High-level event on the Stream implemented by Client and Component
39#[derive(Debug)]
40pub enum Event {
41    /// Stream is connected and initialized
42    Online {
43        /// Server-set Jabber-Id for your session
44        ///
45        /// This may turn out to be a different JID resource than
46        /// expected, so use this one instead of the JID with which
47        /// the connection was setup.
48        bound_jid: Jid,
49        /// Features supported by the server
50        features: StreamFeatures,
51        /// Was this session resumed?
52        ///
53        /// Not yet implemented for the Client
54        resumed: bool,
55    },
56    /// Stream end
57    Disconnected(Error),
58    /// Received stanza/nonza
59    Stanza(Stanza),
60}
61
62impl Event {
63    /// `Online` event?
64    pub fn is_online(&self) -> bool {
65        matches!(&self, Event::Online { .. })
66    }
67
68    /// Get the server-assigned JID for the `Online` event
69    pub fn get_jid(&self) -> Option<&Jid> {
70        match *self {
71            Event::Online { ref bound_jid, .. } => Some(bound_jid),
72            _ => None,
73        }
74    }
75
76    /// If this is a `Stanza` event, get its data
77    pub fn as_stanza(&self) -> Option<&Stanza> {
78        match *self {
79            Event::Stanza(ref stanza) => Some(stanza),
80            _ => None,
81        }
82    }
83
84    /// If this is a `Stanza` event, unwrap into its data
85    pub fn into_stanza(self) -> Option<Stanza> {
86        match self {
87            Event::Stanza(stanza) => Some(stanza),
88            _ => None,
89        }
90    }
91}