diff --git a/xmpp/src/agent.rs b/xmpp/src/agent.rs new file mode 100644 index 0000000..68ded0c --- /dev/null +++ b/xmpp/src/agent.rs @@ -0,0 +1,107 @@ +// Copyright (c) 2023 xmpp-rs contributors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use std::path::{Path, PathBuf}; +use std::sync::{Arc, RwLock}; +pub use tokio_xmpp::parsers; +use tokio_xmpp::parsers::{disco::DiscoInfoResult, message::MessageType}; +use tokio_xmpp::AsyncClient as TokioXmppClient; +pub use tokio_xmpp::{BareJid, Element, FullJid, Jid}; + +use crate::{event_loop, message, muc, upload, Error, Event, RoomNick}; + +pub struct Agent { + pub(crate) client: TokioXmppClient, + pub(crate) default_nick: Arc>, + pub(crate) lang: Arc>, + pub(crate) disco: DiscoInfoResult, + pub(crate) node: String, + pub(crate) uploads: Vec<(String, Jid, PathBuf)>, + pub(crate) awaiting_disco_bookmarks_type: bool, +} + +impl Agent { + pub async fn disconnect(&mut self) -> Result<(), Error> { + self.client.send_end().await + } + + pub async fn join_room( + &mut self, + room: BareJid, + nick: Option, + password: Option, + lang: &str, + status: &str, + ) { + muc::room::join_room(self, room, nick, password, lang, status).await + } + + /// Send a "leave room" request to the server (specifically, an "unavailable" presence stanza). + /// + /// The returned future will resolve when the request has been sent, + /// not when the room has actually been left. + /// + /// If successful, a `RoomLeft` event should be received later as a confirmation. + /// + /// See: https://xmpp.org/extensions/xep-0045.html#exit + /// + /// Note that this method does NOT remove the room from the auto-join list; the latter + /// is more a list of bookmarks that the account knows about and that have a flag set + /// to indicate that they should be joined automatically after connecting (see the JoinRoom event). + /// + /// Regarding the latter, see the these minutes about auto-join behavior: + /// https://docs.modernxmpp.org/meetings/2019-01-brussels/#bookmarks + /// + /// # Arguments + /// + /// * `room_jid`: The JID of the room to leave. + /// * `nickname`: The nickname to use in the room. + /// * `lang`: The language of the status message. + /// * `status`: The status message to send. + pub async fn leave_room( + &mut self, + room_jid: BareJid, + nickname: RoomNick, + lang: impl Into, + status: impl Into, + ) { + muc::room::leave_room(self, room_jid, nickname, lang, status).await + } + + pub async fn send_message( + &mut self, + recipient: Jid, + type_: MessageType, + lang: &str, + text: &str, + ) { + message::send::send_message(self, recipient, type_, lang, text).await + } + + pub async fn send_room_private_message( + &mut self, + room: BareJid, + recipient: RoomNick, + lang: &str, + text: &str, + ) { + muc::private_message::send_room_private_message(self, room, recipient, lang, text).await + } + + /// Wait for new events. + /// + /// # Returns + /// + /// - `Some(events)` if there are new events; multiple may be returned at once. + /// - `None` if the underlying stream is closed. + pub async fn wait_for_events(&mut self) -> Option> { + event_loop::wait_for_events(self).await + } + + pub async fn upload_file_with(&mut self, service: &str, path: &Path) { + upload::send::upload_file_with(self, service, path).await + } +} diff --git a/xmpp/src/lib.rs b/xmpp/src/lib.rs index dc1bd46..7b85c8f 100644 --- a/xmpp/src/lib.rs +++ b/xmpp/src/lib.rs @@ -6,15 +6,12 @@ #![deny(bare_trait_objects)] -use std::path::{Path, PathBuf}; -use std::sync::{Arc, RwLock}; pub use tokio_xmpp::parsers; -use tokio_xmpp::parsers::{disco::DiscoInfoResult, message::MessageType}; -use tokio_xmpp::AsyncClient as TokioXmppClient; pub use tokio_xmpp::{BareJid, Element, FullJid, Jid}; #[macro_use] extern crate log; +pub mod agent; pub mod builder; pub mod disco; pub mod event; @@ -28,6 +25,7 @@ pub mod pubsub; pub mod upload; // Module re-exports +pub use agent::Agent; pub use builder::{ClientBuilder, ClientType}; pub use event::Event; pub use feature::ClientFeature; @@ -36,99 +34,6 @@ pub type Error = tokio_xmpp::Error; pub type Id = Option; pub type RoomNick = String; -pub struct Agent { - client: TokioXmppClient, - default_nick: Arc>, - lang: Arc>, - disco: DiscoInfoResult, - node: String, - uploads: Vec<(String, Jid, PathBuf)>, - awaiting_disco_bookmarks_type: bool, -} - -impl Agent { - pub async fn disconnect(&mut self) -> Result<(), Error> { - self.client.send_end().await - } - - pub async fn join_room( - &mut self, - room: BareJid, - nick: Option, - password: Option, - lang: &str, - status: &str, - ) { - muc::room::join_room(self, room, nick, password, lang, status).await - } - - /// Send a "leave room" request to the server (specifically, an "unavailable" presence stanza). - /// - /// The returned future will resolve when the request has been sent, - /// not when the room has actually been left. - /// - /// If successful, a `RoomLeft` event should be received later as a confirmation. - /// - /// See: https://xmpp.org/extensions/xep-0045.html#exit - /// - /// Note that this method does NOT remove the room from the auto-join list; the latter - /// is more a list of bookmarks that the account knows about and that have a flag set - /// to indicate that they should be joined automatically after connecting (see the JoinRoom event). - /// - /// Regarding the latter, see the these minutes about auto-join behavior: - /// https://docs.modernxmpp.org/meetings/2019-01-brussels/#bookmarks - /// - /// # Arguments - /// - /// * `room_jid`: The JID of the room to leave. - /// * `nickname`: The nickname to use in the room. - /// * `lang`: The language of the status message. - /// * `status`: The status message to send. - pub async fn leave_room( - &mut self, - room_jid: BareJid, - nickname: RoomNick, - lang: impl Into, - status: impl Into, - ) { - muc::room::leave_room(self, room_jid, nickname, lang, status).await - } - - pub async fn send_message( - &mut self, - recipient: Jid, - type_: MessageType, - lang: &str, - text: &str, - ) { - message::send::send_message(self, recipient, type_, lang, text).await - } - - pub async fn send_room_private_message( - &mut self, - room: BareJid, - recipient: RoomNick, - lang: &str, - text: &str, - ) { - muc::private_message::send_room_private_message(self, room, recipient, lang, text).await - } - - /// Wait for new events. - /// - /// # Returns - /// - /// - `Some(events)` if there are new events; multiple may be returned at once. - /// - `None` if the underlying stream is closed. - pub async fn wait_for_events(&mut self) -> Option> { - event_loop::wait_for_events(self).await - } - - pub async fn upload_file_with(&mut self, service: &str, path: &Path) { - upload::send::upload_file_with(self, service, path).await - } -} - #[cfg(test)] mod tests { use super::{Agent, BareJid, ClientBuilder, ClientFeature, ClientType, Event};