parsers/xmpp: MUC bookmarks have nickname typed as ResourcePart
This commit is contained in:
parent
8c033a3fa0
commit
c16456f381
10 changed files with 65 additions and 28 deletions
|
|
@ -34,6 +34,8 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
|
||||||
use them just like normal booleans. The following structs are deprecated:
|
use them just like normal booleans. The following structs are deprecated:
|
||||||
pubsub::pubsub::Notify, bookmarks2::Autojoin, extdisco::Restricted,
|
pubsub::pubsub::Notify, bookmarks2::Autojoin, extdisco::Restricted,
|
||||||
fast::Tls0Rtt, legacy_omemo::IsPreKey, mam::Complete, sm::ResumeAttr (!476)
|
fast::Tls0Rtt, legacy_omemo::IsPreKey, mam::Complete, sm::ResumeAttr (!476)
|
||||||
|
- bookmarks::Conference and bookmarks2::Conference use ResourcePart to store
|
||||||
|
the optional nickname instead of a String (!485)
|
||||||
* Improvements:
|
* Improvements:
|
||||||
- Keep unsupported vCard elements as `minidom::Element`, so that they
|
- Keep unsupported vCard elements as `minidom::Element`, so that they
|
||||||
get serialized back instead of being dropped. We now also test for
|
get serialized back instead of being dropped. We now also test for
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ use xso::{AsXml, FromXml};
|
||||||
use jid::BareJid;
|
use jid::BareJid;
|
||||||
|
|
||||||
pub use crate::bookmarks2;
|
pub use crate::bookmarks2;
|
||||||
|
use crate::jid::ResourcePart;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// A conference bookmark.
|
/// A conference bookmark.
|
||||||
|
|
@ -38,8 +39,8 @@ pub struct Conference {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
|
||||||
/// The nick the user will use to join this conference.
|
/// The nick the user will use to join this conference.
|
||||||
#[xml(extract(default, fields(text(type_ = String))))]
|
#[xml(extract(default, fields(text(type_ = ResourcePart))))]
|
||||||
pub nick: Option<String>,
|
pub nick: Option<ResourcePart>,
|
||||||
|
|
||||||
/// The password required to join this conference.
|
/// The password required to join this conference.
|
||||||
#[xml(extract(default, fields(text(type_ = String))))]
|
#[xml(extract(default, fields(text(type_ = String))))]
|
||||||
|
|
@ -129,6 +130,18 @@ mod tests {
|
||||||
assert_eq!(elem1, elem2);
|
assert_eq!(elem1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_resource() {
|
||||||
|
// This emoji is not valid according to Resource prep
|
||||||
|
let elem: Element = "<storage xmlns='storage:bookmarks'><url name='Example' url='https://example.com/'/><conference autojoin='true' jid='foo@muc.localhost' name='TEST'><nick>Whatever\u{1F469}\u{1F3FE}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F469}\u{1F3FC}</nick></conference></storage>".parse().unwrap();
|
||||||
|
let res = Storage::try_from(elem);
|
||||||
|
assert!(res.is_err());
|
||||||
|
assert_eq!(
|
||||||
|
res.unwrap_err().to_string().as_str(),
|
||||||
|
"text parse error: resource doesn’t pass resourceprep validation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn complete() {
|
fn complete() {
|
||||||
let elem: Element = "<storage xmlns='storage:bookmarks'><url name='Example' url='https://example.org/'/><conference autojoin='true' jid='test-muc@muc.localhost' name='Test MUC'><nick>Coucou</nick><password>secret</password></conference></storage>".parse().unwrap();
|
let elem: Element = "<storage xmlns='storage:bookmarks'><url name='Example' url='https://example.org/'/><conference autojoin='true' jid='test-muc@muc.localhost' name='Test MUC'><nick>Coucou</nick><password>secret</password></conference></storage>".parse().unwrap();
|
||||||
|
|
@ -143,7 +156,10 @@ mod tests {
|
||||||
BareJid::new("test-muc@muc.localhost").unwrap()
|
BareJid::new("test-muc@muc.localhost").unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(storage.conferences[0].clone().name.unwrap(), "Test MUC");
|
assert_eq!(storage.conferences[0].clone().name.unwrap(), "Test MUC");
|
||||||
assert_eq!(storage.conferences[0].clone().nick.unwrap(), "Coucou");
|
assert_eq!(
|
||||||
|
storage.conferences[0].clone().nick.unwrap().as_str(),
|
||||||
|
"Coucou"
|
||||||
|
);
|
||||||
assert_eq!(storage.conferences[0].clone().password.unwrap(), "secret");
|
assert_eq!(storage.conferences[0].clone().password.unwrap(), "secret");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
use xso::{AsXml, FromXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
|
use crate::jid::ResourcePart;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use minidom::Element;
|
use minidom::Element;
|
||||||
|
|
||||||
|
|
@ -39,8 +40,8 @@ pub struct Conference {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
|
||||||
/// The nick the user will use to join this conference.
|
/// The nick the user will use to join this conference.
|
||||||
#[xml(extract(default, fields(text(type_ = String))))]
|
#[xml(extract(default, fields(text(type_ = ResourcePart))))]
|
||||||
pub nick: Option<String>,
|
pub nick: Option<ResourcePart>,
|
||||||
|
|
||||||
/// The password required to join this conference.
|
/// The password required to join this conference.
|
||||||
#[xml(extract(default, fields(text(type_ = String))))]
|
#[xml(extract(default, fields(text(type_ = String))))]
|
||||||
|
|
@ -91,13 +92,25 @@ mod tests {
|
||||||
assert_eq!(elem1, elem2);
|
assert_eq!(elem1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_resource() {
|
||||||
|
// This emoji is not valid according to Resource prep
|
||||||
|
let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:1' autojoin='true'><nick>Whatever\u{1F469}\u{1F3FE}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F469}\u{1F3FC}</nick></conference>".parse().unwrap();
|
||||||
|
let res = Conference::try_from(elem);
|
||||||
|
assert!(res.is_err());
|
||||||
|
assert_eq!(
|
||||||
|
res.unwrap_err().to_string().as_str(),
|
||||||
|
"text parse error: resource doesn’t pass resourceprep validation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn complete() {
|
fn complete() {
|
||||||
let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password><extensions><test xmlns='urn:xmpp:unknown' /></extensions></conference>".parse().unwrap();
|
let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password><extensions><test xmlns='urn:xmpp:unknown' /></extensions></conference>".parse().unwrap();
|
||||||
let conference = Conference::try_from(elem).unwrap();
|
let conference = Conference::try_from(elem).unwrap();
|
||||||
assert_eq!(conference.autojoin, true);
|
assert_eq!(conference.autojoin, true);
|
||||||
assert_eq!(conference.name, Some(String::from("Test MUC")));
|
assert_eq!(conference.name, Some(String::from("Test MUC")));
|
||||||
assert_eq!(conference.clone().nick.unwrap(), "Coucou");
|
assert_eq!(conference.clone().nick.unwrap().as_str(), "Coucou");
|
||||||
assert_eq!(conference.clone().password.unwrap(), "secret");
|
assert_eq!(conference.clone().password.unwrap(), "secret");
|
||||||
let payloads = conference.clone().extensions.unwrap().payloads;
|
let payloads = conference.clone().extensions.unwrap().payloads;
|
||||||
assert_eq!(payloads.len(), 1);
|
assert_eq!(payloads.len(), 1);
|
||||||
|
|
@ -115,7 +128,7 @@ mod tests {
|
||||||
println!("FOO: conference: {:?}", conference);
|
println!("FOO: conference: {:?}", conference);
|
||||||
assert_eq!(conference.autojoin, true);
|
assert_eq!(conference.autojoin, true);
|
||||||
assert_eq!(conference.name, Some(String::from("Test MUC")));
|
assert_eq!(conference.name, Some(String::from("Test MUC")));
|
||||||
assert_eq!(conference.clone().nick.unwrap(), "Coucou");
|
assert_eq!(conference.clone().nick.unwrap().as_str(), "Coucou");
|
||||||
assert_eq!(conference.clone().password.unwrap(), "secret");
|
assert_eq!(conference.clone().password.unwrap(), "secret");
|
||||||
|
|
||||||
let elem: Element = "<event xmlns='http://jabber.org/protocol/pubsub#event'><items node='urn:xmpp:bookmarks:1'><item xmlns='http://jabber.org/protocol/pubsub#event' id='test-muc@muc.localhost'><conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password></conference></item></items></event>".parse().unwrap();
|
let elem: Element = "<event xmlns='http://jabber.org/protocol/pubsub#event'><items node='urn:xmpp:bookmarks:1'><item xmlns='http://jabber.org/protocol/pubsub#event' id='test-muc@muc.localhost'><conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password></conference></item></items></event>".parse().unwrap();
|
||||||
|
|
@ -132,7 +145,7 @@ mod tests {
|
||||||
let conference = Conference::try_from(payload).unwrap();
|
let conference = Conference::try_from(payload).unwrap();
|
||||||
assert_eq!(conference.autojoin, true);
|
assert_eq!(conference.autojoin, true);
|
||||||
assert_eq!(conference.name, Some(String::from("Test MUC")));
|
assert_eq!(conference.name, Some(String::from("Test MUC")));
|
||||||
assert_eq!(conference.clone().nick.unwrap(), "Coucou");
|
assert_eq!(conference.clone().nick.unwrap().as_str(), "Coucou");
|
||||||
assert_eq!(conference.clone().password.unwrap(), "secret");
|
assert_eq!(conference.clone().password.unwrap(), "secret");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ XXXX-YY-ZZ [ RELEASER <admin@localhost> ]
|
||||||
Agent now handles MUC connection states internally. (!481)
|
Agent now handles MUC connection states internally. (!481)
|
||||||
- Agent::leave_room now takes LeaveRoomSettings argument (!483)
|
- Agent::leave_room now takes LeaveRoomSettings argument (!483)
|
||||||
- Agent::join_room now takes JoinRoomSettings argument (!483)
|
- Agent::join_room now takes JoinRoomSettings argument (!483)
|
||||||
|
- builder::ClientBuilder::set_default_nick no longer takes a &str, but
|
||||||
|
any type that implements AsRef<jid::ResourceRef>, such as produced
|
||||||
|
by ResourcePart::new (!485)
|
||||||
* Added:
|
* Added:
|
||||||
- Agent::send_room_message takes RoomMessageSettings argument (!483)
|
- Agent::send_room_message takes RoomMessageSettings argument (!483)
|
||||||
* Fixes:
|
* Fixes:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tokio_xmpp::jid::BareJid;
|
use tokio_xmpp::jid::{BareJid, ResourcePart};
|
||||||
use xmpp::muc::room::{JoinRoomSettings, RoomMessageSettings};
|
use xmpp::muc::room::{JoinRoomSettings, RoomMessageSettings};
|
||||||
use xmpp::{ClientBuilder, ClientFeature, ClientType, Event};
|
use xmpp::{ClientBuilder, ClientFeature, ClientType, Event};
|
||||||
|
|
||||||
|
|
@ -39,11 +39,13 @@ async fn main() -> Result<(), Option<()>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let nick = ResourcePart::new("bot").unwrap();
|
||||||
|
|
||||||
// Client instance
|
// Client instance
|
||||||
let mut client = ClientBuilder::new(jid, password)
|
let mut client = ClientBuilder::new(jid, password)
|
||||||
.set_client(ClientType::Bot, "xmpp-rs")
|
.set_client(ClientType::Bot, "xmpp-rs")
|
||||||
.set_website("https://gitlab.com/xmpp-rs/xmpp-rs")
|
.set_website("https://gitlab.com/xmpp-rs/xmpp-rs")
|
||||||
.set_default_nick("bot")
|
.set_default_nick(nick)
|
||||||
.enable_feature(ClientFeature::ContactList)
|
.enable_feature(ClientFeature::ContactList)
|
||||||
.enable_feature(ClientFeature::JoinRooms)
|
.enable_feature(ClientFeature::JoinRooms)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use tokio::sync::RwLock;
|
||||||
pub use tokio_xmpp::parsers;
|
pub use tokio_xmpp::parsers;
|
||||||
use tokio_xmpp::parsers::{disco::DiscoInfoResult, message::MessageType};
|
use tokio_xmpp::parsers::{disco::DiscoInfoResult, message::MessageType};
|
||||||
pub use tokio_xmpp::{
|
pub use tokio_xmpp::{
|
||||||
jid::{BareJid, FullJid, Jid},
|
jid::{BareJid, FullJid, Jid, ResourcePart},
|
||||||
minidom::Element,
|
minidom::Element,
|
||||||
Client as TokioXmppClient,
|
Client as TokioXmppClient,
|
||||||
};
|
};
|
||||||
|
|
@ -20,16 +20,16 @@ use crate::{event_loop, message, muc, upload, Error, Event, RoomNick};
|
||||||
|
|
||||||
pub struct Agent {
|
pub struct Agent {
|
||||||
pub(crate) client: TokioXmppClient,
|
pub(crate) client: TokioXmppClient,
|
||||||
pub(crate) default_nick: Arc<RwLock<String>>,
|
pub(crate) default_nick: Arc<RwLock<ResourcePart>>,
|
||||||
pub(crate) lang: Arc<Vec<String>>,
|
pub(crate) lang: Arc<Vec<String>>,
|
||||||
pub(crate) disco: DiscoInfoResult,
|
pub(crate) disco: DiscoInfoResult,
|
||||||
pub(crate) node: String,
|
pub(crate) node: String,
|
||||||
pub(crate) uploads: Vec<(String, Jid, PathBuf)>,
|
pub(crate) uploads: Vec<(String, Jid, PathBuf)>,
|
||||||
pub(crate) awaiting_disco_bookmarks_type: bool,
|
pub(crate) awaiting_disco_bookmarks_type: bool,
|
||||||
// Mapping of room->nick
|
// Mapping of room->nick
|
||||||
pub(crate) rooms_joined: HashMap<BareJid, String>,
|
pub(crate) rooms_joined: HashMap<BareJid, ResourcePart>,
|
||||||
pub(crate) rooms_joining: HashMap<BareJid, String>,
|
pub(crate) rooms_joining: HashMap<BareJid, ResourcePart>,
|
||||||
pub(crate) rooms_leaving: HashMap<BareJid, String>,
|
pub(crate) rooms_leaving: HashMap<BareJid, ResourcePart>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Agent {
|
impl Agent {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use tokio::sync::RwLock;
|
||||||
use tokio_xmpp::connect::{DnsConfig, StartTlsServerConnector};
|
use tokio_xmpp::connect::{DnsConfig, StartTlsServerConnector};
|
||||||
use tokio_xmpp::{
|
use tokio_xmpp::{
|
||||||
connect::ServerConnector,
|
connect::ServerConnector,
|
||||||
jid::{BareJid, Jid},
|
jid::{BareJid, Jid, ResourcePart, ResourceRef},
|
||||||
parsers::{
|
parsers::{
|
||||||
disco::{DiscoInfoResult, Feature, Identity},
|
disco::{DiscoInfoResult, Feature, Identity},
|
||||||
ns,
|
ns,
|
||||||
|
|
@ -48,7 +48,7 @@ pub struct ClientBuilder<'a, C: ServerConnector> {
|
||||||
password: &'a str,
|
password: &'a str,
|
||||||
server_connector: C,
|
server_connector: C,
|
||||||
website: String,
|
website: String,
|
||||||
default_nick: String,
|
default_nick: ResourcePart,
|
||||||
lang: Vec<String>,
|
lang: Vec<String>,
|
||||||
disco: (ClientType, String),
|
disco: (ClientType, String),
|
||||||
features: Vec<ClientFeature>,
|
features: Vec<ClientFeature>,
|
||||||
|
|
@ -78,7 +78,7 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
|
||||||
password,
|
password,
|
||||||
server_connector,
|
server_connector,
|
||||||
website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
|
website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
|
||||||
default_nick: String::from("xmpp-rs"),
|
default_nick: ResourcePart::new("xmpp-rs").unwrap().into(),
|
||||||
lang: vec![String::from("en")],
|
lang: vec![String::from("en")],
|
||||||
disco: (ClientType::default(), String::from("tokio-xmpp")),
|
disco: (ClientType::default(), String::from("tokio-xmpp")),
|
||||||
features: vec![],
|
features: vec![],
|
||||||
|
|
@ -103,8 +103,8 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_default_nick(mut self, nick: &str) -> Self {
|
pub fn set_default_nick(mut self, nick: impl AsRef<ResourceRef>) -> Self {
|
||||||
self.default_nick = String::from(nick);
|
self.default_nick = nick.as_ref().to_owned();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ pub type RoomNick = String;
|
||||||
/*
|
/*
|
||||||
#[cfg(all(test, any(feature = "starttls-rust", feature = "starttls-native")))]
|
#[cfg(all(test, any(feature = "starttls-rust", feature = "starttls-native")))]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::jid::BareJid;
|
use super::jid::{BareJid, ResourcePart};
|
||||||
use super::{ClientBuilder, ClientFeature, ClientType, Event};
|
use super::{ClientBuilder, ClientFeature, ClientType, Event};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tokio_xmpp::Client as TokioXmppClient;
|
use tokio_xmpp::Client as TokioXmppClient;
|
||||||
|
|
@ -52,6 +52,7 @@ mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_simple() {
|
async fn test_simple() {
|
||||||
let jid = BareJid::from_str("foo@bar").unwrap();
|
let jid = BareJid::from_str("foo@bar").unwrap();
|
||||||
|
let nick = ResourcePart::new("bot").unwrap();
|
||||||
|
|
||||||
let client = TokioXmppClient::new(jid.clone(), "meh");
|
let client = TokioXmppClient::new(jid.clone(), "meh");
|
||||||
|
|
||||||
|
|
@ -59,7 +60,7 @@ mod tests {
|
||||||
let client_builder = ClientBuilder::new(jid, "meh")
|
let client_builder = ClientBuilder::new(jid, "meh")
|
||||||
.set_client(ClientType::Bot, "xmpp-rs")
|
.set_client(ClientType::Bot, "xmpp-rs")
|
||||||
.set_website("https://gitlab.com/xmpp-rs/xmpp-rs")
|
.set_website("https://gitlab.com/xmpp-rs/xmpp-rs")
|
||||||
.set_default_nick("bot")
|
.set_default_nick(nick)
|
||||||
.enable_feature(ClientFeature::ContactList);
|
.enable_feature(ClientFeature::ContactList);
|
||||||
|
|
||||||
#[cfg(feature = "avatars")]
|
#[cfg(feature = "avatars")]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use crate::parsers::message::MessageType;
|
use crate::parsers::message::MessageType;
|
||||||
use tokio_xmpp::{
|
use tokio_xmpp::{
|
||||||
jid::BareJid,
|
jid::{BareJid, ResourcePart, ResourceRef},
|
||||||
parsers::{
|
parsers::{
|
||||||
muc::Muc,
|
muc::Muc,
|
||||||
presence::{Presence, Type as PresenceType},
|
presence::{Presence, Type as PresenceType},
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::Agent;
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct JoinRoomSettings<'a> {
|
pub struct JoinRoomSettings<'a> {
|
||||||
pub room: BareJid,
|
pub room: BareJid,
|
||||||
pub nick: Option<String>,
|
pub nick: Option<ResourcePart>,
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
pub status: Option<(&'a str, &'a str)>,
|
pub status: Option<(&'a str, &'a str)>,
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ impl<'a> JoinRoomSettings<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_nick(mut self, nick: impl AsRef<str>) -> Self {
|
pub fn with_nick(mut self, nick: impl AsRef<ResourceRef>) -> Self {
|
||||||
self.nick = Some(nick.as_ref().into());
|
self.nick = Some(nick.as_ref().into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ pub async fn join_room<'a>(agent: &mut Agent, settings: JoinRoomSettings<'a>) {
|
||||||
agent.default_nick.read().await.clone()
|
agent.default_nick.read().await.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let room_jid = room.with_resource_str(&nick).unwrap();
|
let room_jid = room.with_resource(&nick);
|
||||||
let mut presence = Presence::new(PresenceType::None).with_to(room_jid);
|
let mut presence = Presence::new(PresenceType::None).with_to(room_jid);
|
||||||
presence.add_payload(muc);
|
presence.add_payload(muc);
|
||||||
|
|
||||||
|
|
@ -156,7 +156,7 @@ pub async fn leave_room<'a>(agent: &mut Agent, settings: LeaveRoomSettings<'a>)
|
||||||
error!("Failed to send leave room presence: {}", e);
|
error!("Failed to send leave room presence: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
agent.rooms_leaving.insert(room, nickname.to_string());
|
agent.rooms_leaving.insert(room, nickname.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub async fn handle_presence(agent: &mut Agent, presence: Presence) -> Vec<Event
|
||||||
PresenceType::None => {
|
PresenceType::None => {
|
||||||
// According to https://xmpp.org/extensions/xep-0045.html#enter-pres, no type should be seen as "available".
|
// According to https://xmpp.org/extensions/xep-0045.html#enter-pres, no type should be seen as "available".
|
||||||
if let Some(nick) = agent.rooms_joining.get(&from) {
|
if let Some(nick) = agent.rooms_joining.get(&from) {
|
||||||
agent.rooms_joined.insert(from.clone(), nick.to_string());
|
agent.rooms_joined.insert(from.clone(), nick.clone());
|
||||||
agent.rooms_joining.remove(&from);
|
agent.rooms_joining.remove(&from);
|
||||||
} else {
|
} else {
|
||||||
warn!("Received self-presence from {} while the room was not marked as joining.", presence.from.unwrap());
|
warn!("Received self-presence from {} while the room was not marked as joining.", presence.from.unwrap());
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue