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}