lib.rs

  1// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  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
  7#![deny(bare_trait_objects)]
  8#![cfg_attr(docsrs, feature(doc_auto_cfg))]
  9
 10extern crate alloc;
 11
 12pub use tokio_xmpp;
 13pub use tokio_xmpp::jid;
 14pub use tokio_xmpp::minidom;
 15pub use tokio_xmpp::parsers;
 16
 17#[macro_use]
 18extern crate log;
 19
 20use core::fmt;
 21use jid::{ResourcePart, ResourceRef};
 22use parsers::message::Id as MessageId;
 23
 24pub mod agent;
 25pub mod builder;
 26pub mod delay;
 27pub mod disco;
 28pub mod event;
 29pub mod event_loop;
 30pub mod feature;
 31pub mod iq;
 32pub mod message;
 33pub mod muc;
 34pub mod presence;
 35pub mod pubsub;
 36pub mod upload;
 37
 38pub use agent::Agent;
 39pub use builder::{ClientBuilder, ClientType};
 40pub use event::Event;
 41pub use feature::ClientFeature;
 42
 43pub type Error = tokio_xmpp::Error;
 44
 45/// Nickname for a person in a chatroom.
 46///
 47/// This nickname is not associated with a specific chatroom, or with a certain
 48/// user account.
 49///
 50// TODO: Introduce RoomMember and track by occupant-id
 51#[derive(Clone, Debug)]
 52pub struct RoomNick(ResourcePart);
 53
 54impl RoomNick {
 55    pub fn new(nick: ResourcePart) -> Self {
 56        Self(nick)
 57    }
 58
 59    pub fn from_resource_ref(nick: &ResourceRef) -> Self {
 60        Self(nick.to_owned())
 61    }
 62}
 63
 64impl AsRef<ResourceRef> for RoomNick {
 65    fn as_ref(&self) -> &ResourceRef {
 66        self.0.as_ref()
 67    }
 68}
 69
 70impl From<RoomNick> for ResourcePart {
 71    fn from(room_nick: RoomNick) -> Self {
 72        room_nick.0
 73    }
 74}
 75
 76impl fmt::Display for RoomNick {
 77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 78        write!(f, "{}", self.0)
 79    }
 80}
 81
 82impl core::str::FromStr for RoomNick {
 83    type Err = crate::jid::Error;
 84
 85    fn from_str(s: &str) -> Result<Self, Self::Err> {
 86        Ok(Self::new(ResourcePart::new(s)?.into()))
 87    }
 88}
 89
 90impl core::ops::Deref for RoomNick {
 91    type Target = ResourcePart;
 92
 93    fn deref(&self) -> &ResourcePart {
 94        &self.0
 95    }
 96}
 97
 98#[cfg(test)]
 99mod tests {
100    #[test]
101    fn reexports() {
102        #[allow(unused_imports)]
103        use crate::jid;
104        #[allow(unused_imports)]
105        use crate::minidom;
106        #[allow(unused_imports)]
107        use crate::parsers;
108        #[allow(unused_imports)]
109        use crate::tokio_xmpp;
110    }
111}
112
113// The test below is dysfunctional since we have moved to StanzaStream. The
114// StanzaStream will attempt to connect to foo@bar indefinitely.
115// Keeping it here as inspiration for future integration tests.
116/*
117#[cfg(all(test, any(feature = "starttls-rust", feature = "starttls-native")))]
118mod tests {
119    use super::jid::{BareJid, ResourcePart};
120    use super::{ClientBuilder, ClientFeature, ClientType, Event};
121    use std::str::FromStr;
122    use tokio_xmpp::Client as TokioXmppClient;
123
124    #[tokio::test]
125    async fn test_simple() {
126        let jid = BareJid::from_str("foo@bar").unwrap();
127        let nick = RoomNick::from_str("bot").unwrap();
128
129        let client = TokioXmppClient::new(jid.clone(), "meh");
130
131        // Client instance
132        let client_builder = ClientBuilder::new(jid, "meh")
133            .set_client(ClientType::Bot, "xmpp-rs")
134            .set_website("https://gitlab.com/xmpp-rs/xmpp-rs")
135            .set_default_nick(nick)
136            .enable_feature(ClientFeature::ContactList);
137
138        #[cfg(feature = "avatars")]
139        let client_builder = client_builder.enable_feature(ClientFeature::Avatars);
140
141        let mut agent = client_builder.build_impl(client);
142
143        loop {
144            let events = agent.wait_for_events().await;
145            assert!(match events[0] {
146                Event::Disconnected(_) => true,
147                _ => false,
148            });
149            assert_eq!(events.len(), 1);
150            break;
151        }
152    }
153}
154*/