Update xmpp (tokio-xmpp, jid) deps

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-10-26 00:48:24 +02:00
parent bad6a425a8
commit 49af4e44f7
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
9 changed files with 87 additions and 74 deletions

View file

@ -14,8 +14,10 @@ futures = "^0.3"
lazy_static = "^1.4" lazy_static = "^1.4"
log = "^0.4" log = "^0.4"
tokio = "^1.20" tokio = "^1.20"
tokio-xmpp = { version = "^3.2", default-features = false, features = ["tls-rust"] } tokio-xmpp = { version = "^3.5", default-features = false, features = ["tls-rust"] }
xmpp-parsers = { version = "^0.19", features = ["component"] } xmpp-parsers = { version = "*", features = ["component"] }
minidom = { version = "*" }
jid = { version = "*" }
[dev-dependencies] [dev-dependencies]
syntect = "5.0" syntect = "5.0"

View file

@ -96,22 +96,24 @@ async fn handle_iq_ping<C: ComponentTrait>(
// Pinging a participant. The resource needs to be currently joined. // Pinging a participant. The resource needs to be currently joined.
if let Jid::Full(participant) = to.clone() { if let Jid::Full(participant) = to.clone() {
// TODO: Reply from participant if joined and nick is correct // TODO: Reply from participant if joined and nick is correct
let bare = BareJid::from(to.clone()); let bare = BareJid::from(to.clone().to_bare());
if let Some(room) = rooms.get(&bare) && let nick = participant.resource_str();
room.is_joined(&participant) && if let Some(room) = rooms.get(&bare)
let Some(occupant) = room.occupants.get(&participant.resource) { && room.is_joined(&participant)
if occupant.contains(&from) { && let Some(occupant) = room.occupants.get(nick)
let success = success.clone().with_from(Jid::Full(participant)); {
component.send_stanza(success).await?; if occupant.contains(&from) {
return Ok(()); let success = success.clone().with_from(Jid::Full(participant));
} component.send_stanza(success).await?;
return Ok(());
}
return Ok(()); return Ok(());
} }
} else if let Jid::Bare(to) = to.clone() { } else if let Jid::Bare(to) = to.clone() {
// Pinging the component // Pinging the component
if to.node.is_none() { if to.node().is_none() {
let domain = BareJid::from_str(&to.domain).unwrap(); let domain = BareJid::from_str(to.domain_str()).unwrap();
let success = success.clone().with_from(Jid::Bare(domain)); let success = success.clone().with_from(Jid::Bare(domain));
component.send_stanza(success).await?; component.send_stanza(success).await?;
// Pinging a room. User is required to have an affiliation other than none if // Pinging a room. User is required to have an affiliation other than none if
@ -130,7 +132,7 @@ async fn handle_iq_ping<C: ComponentTrait>(
StanzaError { StanzaError {
type_: ErrorType::Modify, type_: ErrorType::Modify,
defined_condition: DefinedCondition::NotAcceptable, defined_condition: DefinedCondition::NotAcceptable,
by: Some(Jid::Bare(BareJid::from(to.clone()))), by: Some(Jid::Bare(BareJid::from(to.to_bare()))),
texts: BTreeMap::new(), texts: BTreeMap::new(),
other: None, other: None,
}, },

View file

@ -88,7 +88,7 @@ async fn handle_presence_full_available<C: ComponentTrait>(
.unwrap() .unwrap()
.unwrap(); .unwrap();
let participant: FullJid = presence.to.clone().map(FullJid::try_from).unwrap().unwrap(); let participant: FullJid = presence.to.clone().map(FullJid::try_from).unwrap().unwrap();
let roomjid: BareJid = BareJid::from(participant.clone()); let roomjid: BareJid = BareJid::from(participant.to_bare());
let muc = presence let muc = presence
.payloads .payloads
@ -172,7 +172,7 @@ async fn handle_presence_full_unavailable<C: ComponentTrait>(
.unwrap() .unwrap()
.unwrap(); .unwrap();
let participant: FullJid = presence.to.clone().map(FullJid::try_from).unwrap().unwrap(); let participant: FullJid = presence.to.clone().map(FullJid::try_from).unwrap().unwrap();
let roomjid: BareJid = BareJid::from(participant.clone()); let roomjid: BareJid = BareJid::from(participant.to_bare());
let error = Presence::new(PresenceType::Error) let error = Presence::new(PresenceType::Error)
.with_from(participant.clone()) .with_from(participant.clone())

View file

@ -14,7 +14,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#![feature(let_chains)] #![feature(let_chains)]
#![feature(once_cell)] #![feature(lazy_cell)]
// Maybe change that someday? // Maybe change that someday?
#![allow(clippy::result_large_err)] #![allow(clippy::result_large_err)]

View file

@ -37,8 +37,8 @@ impl Occupant {
let participant = presence.to.clone().map(FullJid::try_from).unwrap().unwrap(); let participant = presence.to.clone().map(FullJid::try_from).unwrap().unwrap();
let session = Session::try_from(presence)?; let session = Session::try_from(presence)?;
Ok(Occupant { Ok(Occupant {
real: BareJid::from(session.real().clone()), real: BareJid::from(session.real().to_bare()),
nick: participant.resource.clone(), nick: participant.resource_str().to_string(),
participant, participant,
sessions: vec![session], sessions: vec![session],
}) })
@ -64,7 +64,7 @@ impl Occupant {
/// Add a new session to the occupant /// Add a new session to the occupant
pub fn add_session(&mut self, presence: PresenceFull) -> Result<(), Error> { pub fn add_session(&mut self, presence: PresenceFull) -> Result<(), Error> {
let new_session = Session::try_from(presence)?; let new_session = Session::try_from(presence)?;
if BareJid::from(new_session.real().clone()) != self.real { if BareJid::from(new_session.real().to_bare()) != self.real {
return Err(Error::MismatchJids( return Err(Error::MismatchJids(
Jid::from(self.real.clone()), Jid::from(self.real.clone()),
Jid::from(new_session.real().clone()), Jid::from(new_session.real().clone()),

View file

@ -311,13 +311,13 @@ impl Room {
presence: PresenceFull, presence: PresenceFull,
) -> Result<(), Error> { ) -> Result<(), Error> {
let new_session = Session::try_from(presence)?; let new_session = Session::try_from(presence)?;
let new_nick = new_session.participant().resource.clone(); let new_nick = new_session.participant().resource_str().to_string();
let realjid = new_session.real().clone(); let realjid = new_session.real().clone();
// Ensure nick isn't already assigned // Ensure nick isn't already assigned
self.occupants.iter().try_for_each(|(nick, occupant)| { self.occupants.iter().try_for_each(|(nick, occupant)| {
let new_nick = new_nick.as_str(); let new_nick = new_nick.as_str();
if new_nick == nick && occupant.real != BareJid::from(realjid.clone()) { if new_nick == nick && occupant.real != BareJid::from(realjid.to_bare()) {
return Err(Error::NickAlreadyAssigned(String::from(new_nick))); return Err(Error::NickAlreadyAssigned(String::from(new_nick)));
} }
Ok(()) Ok(())
@ -407,15 +407,15 @@ impl Room {
joined_session: Session, joined_session: Session,
new_session: Session, new_session: Session,
) -> Result<(), Error> { ) -> Result<(), Error> {
let oldnick = &joined_session.participant().resource; let oldnick = joined_session.participant().resource_str();
let newnick = &new_session.participant().resource; let newnick = new_session.participant().resource_str();
let bare = BareJid::from(new_session.real().clone()); let bare = BareJid::from(new_session.real().to_bare());
let mut merge = false; let mut merge = false;
for (nick, occupant) in self.occupants.iter_mut() { for (nick, occupant) in self.occupants.iter_mut() {
if nick == newnick { if nick == newnick {
if occupant.real != bare { if occupant.real != bare {
return Err(Error::NickAlreadyAssigned(newnick.clone())); return Err(Error::NickAlreadyAssigned(String::from(newnick)));
} else { } else {
merge = true; merge = true;
break; break;
@ -430,7 +430,7 @@ impl Room {
self.get_occupant(&joined_session)?, self.get_occupant(&joined_session)?,
joined_session.presence.clone(), joined_session.presence.clone(),
BroadcastPresence::Leave, BroadcastPresence::Leave,
Some(&**newnick), Some(&String::from(newnick)),
) )
.await?; .await?;
@ -533,7 +533,8 @@ impl Room {
) -> Result<(), Error> { ) -> Result<(), Error> {
let session = Session::try_from(presence)?; let session = Session::try_from(presence)?;
// If occupant doesn't exist, ignore. // If occupant doesn't exist, ignore.
if let Some(mut occupant) = self.occupants.remove(&session.participant().resource) { let nick = session.participant().resource_str();
if let Some(mut occupant) = self.occupants.remove(nick) {
self.broadcast_presence( self.broadcast_presence(
component, component,
&occupant, &occupant,
@ -547,7 +548,7 @@ impl Room {
if occupant.iter().len() > 0 { if occupant.iter().len() > 0 {
let _ = self let _ = self
.occupants .occupants
.insert(session.participant().resource.clone(), occupant); .insert(session.participant().resource_str().to_string(), occupant);
} }
} else { } else {
// TODO: Error // TODO: Error
@ -590,7 +591,10 @@ impl Room {
/// . /// .
/// Fetch a mutable reference to the occupant associated with the requesting realjid. /// Fetch a mutable reference to the occupant associated with the requesting realjid.
pub fn get_mut_occupant(&mut self, session: &Session) -> Result<&mut Occupant, Error> { pub fn get_mut_occupant(&mut self, session: &Session) -> Result<&mut Occupant, Error> {
if let Some(occupant) = self.occupants.get_mut(&session.participant().resource) { if let Some(occupant) = self
.occupants
.get_mut(&session.participant().resource_str().to_string())
{
if occupant.contains(session.real()) { if occupant.contains(session.real()) {
Ok(occupant) Ok(occupant)
} else { } else {
@ -598,7 +602,7 @@ impl Room {
} }
} else { } else {
Err(Error::ParticipantNotFound( Err(Error::ParticipantNotFound(
session.participant().resource.clone(), session.participant().resource_str().to_string(),
)) ))
} }
} }
@ -631,11 +635,11 @@ mod tests {
async fn broadcast_presence_resync() { async fn broadcast_presence_resync() {
let roomjid = BareJid::from_str("room@muc").unwrap(); let roomjid = BareJid::from_str("room@muc").unwrap();
let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap(); let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap();
let participant1 = roomjid.clone().with_resource(String::from("nick1")); let participant1 = roomjid.clone().with_resource_str("nick1").unwrap();
let realjid2 = FullJid::from_str("qxx@foo/bar").unwrap(); let realjid2 = FullJid::from_str("qxx@foo/bar").unwrap();
let participant2 = roomjid.clone().with_resource(String::from("nick2")); let participant2 = roomjid.clone().with_resource_str("nick2").unwrap();
let realjid3 = FullJid::from_str("bar@qxx/foo").unwrap(); let realjid3 = FullJid::from_str("bar@qxx/foo").unwrap();
let participant3 = roomjid.clone().with_resource(String::from("nick3")); let participant3 = roomjid.clone().with_resource_str("nick3").unwrap();
let presence1 = PresenceFull::try_from( let presence1 = PresenceFull::try_from(
Presence::new(PresenceType::None) Presence::new(PresenceType::None)
@ -662,16 +666,16 @@ mod tests {
room.occupants = BTreeMap::new(); room.occupants = BTreeMap::new();
room.occupants.insert( room.occupants.insert(
participant1.resource.clone(), participant1.resource_str().to_string(),
Occupant::new(presence1).unwrap(), Occupant::new(presence1).unwrap(),
); );
room.occupants.insert( room.occupants.insert(
participant2.resource.clone(), participant2.resource_str().to_string(),
Occupant::new(presence2).unwrap(), Occupant::new(presence2).unwrap(),
); );
let occupant3 = Occupant::new(presence3.clone()).unwrap(); let occupant3 = Occupant::new(presence3.clone()).unwrap();
room.occupants room.occupants
.insert(participant3.resource.clone(), occupant3.clone()); .insert(participant3.resource_str().to_string(), occupant3.clone());
let self_item = MucItem::try_from( let self_item = MucItem::try_from(
r#"<item xmlns="http://jabber.org/protocol/muc#user" affiliation="owner" role="moderator" jid="bar@qxx/foo"/>"# r#"<item xmlns="http://jabber.org/protocol/muc#user" affiliation="owner" role="moderator" jid="bar@qxx/foo"/>"#
@ -730,11 +734,11 @@ mod tests {
async fn broadcast_presence_update() { async fn broadcast_presence_update() {
let roomjid = BareJid::from_str("room@muc").unwrap(); let roomjid = BareJid::from_str("room@muc").unwrap();
let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap(); let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap();
let participant1 = roomjid.clone().with_resource(String::from("nick1")); let participant1 = roomjid.clone().with_resource_str("nick1").unwrap();
let realjid2 = FullJid::from_str("qxx@foo/bar").unwrap(); let realjid2 = FullJid::from_str("qxx@foo/bar").unwrap();
let participant2 = roomjid.clone().with_resource(String::from("nick2")); let participant2 = roomjid.clone().with_resource_str("nick2").unwrap();
let realjid3 = FullJid::from_str("bar@qxx/foo").unwrap(); let realjid3 = FullJid::from_str("bar@qxx/foo").unwrap();
let participant3 = roomjid.clone().with_resource(String::from("nick3")); let participant3 = roomjid.clone().with_resource_str("nick3").unwrap();
let presence1 = PresenceFull::try_from( let presence1 = PresenceFull::try_from(
Presence::new(PresenceType::None) Presence::new(PresenceType::None)
@ -761,16 +765,16 @@ mod tests {
room.occupants = BTreeMap::new(); room.occupants = BTreeMap::new();
room.occupants.insert( room.occupants.insert(
participant1.resource.clone(), participant1.resource_str().to_string(),
Occupant::new(presence1).unwrap(), Occupant::new(presence1).unwrap(),
); );
room.occupants.insert( room.occupants.insert(
participant2.resource.clone(), participant2.resource_str().to_string(),
Occupant::new(presence2).unwrap(), Occupant::new(presence2).unwrap(),
); );
let occupant3 = Occupant::new(presence3.clone()).unwrap(); let occupant3 = Occupant::new(presence3.clone()).unwrap();
room.occupants room.occupants
.insert(participant3.resource.clone(), occupant3.clone()); .insert(participant3.resource_str().to_string(), occupant3.clone());
// BroadcastPresence::Update // BroadcastPresence::Update
let mut component = TestComponent::new(vec![]); let mut component = TestComponent::new(vec![]);
@ -812,11 +816,11 @@ mod tests {
async fn broadcast_presence_join() { async fn broadcast_presence_join() {
let roomjid = BareJid::from_str("room@muc").unwrap(); let roomjid = BareJid::from_str("room@muc").unwrap();
let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap(); let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap();
let participant1 = roomjid.clone().with_resource(String::from("nick1")); let participant1 = roomjid.clone().with_resource_str("nick1").unwrap();
let realjid2 = FullJid::from_str("qxx@foo/bar").unwrap(); let realjid2 = FullJid::from_str("qxx@foo/bar").unwrap();
let participant2 = roomjid.clone().with_resource(String::from("nick2")); let participant2 = roomjid.clone().with_resource_str("nick2").unwrap();
let realjid3 = FullJid::from_str("bar@qxx/foo").unwrap(); let realjid3 = FullJid::from_str("bar@qxx/foo").unwrap();
let participant3 = roomjid.clone().with_resource(String::from("nick3")); let participant3 = roomjid.clone().with_resource_str("nick3").unwrap();
let presence1 = PresenceFull::try_from( let presence1 = PresenceFull::try_from(
Presence::new(PresenceType::None) Presence::new(PresenceType::None)
@ -843,16 +847,16 @@ mod tests {
room.occupants = BTreeMap::new(); room.occupants = BTreeMap::new();
room.occupants.insert( room.occupants.insert(
participant1.resource.clone(), participant1.resource_str().to_string(),
Occupant::new(presence1.clone()).unwrap(), Occupant::new(presence1.clone()).unwrap(),
); );
room.occupants.insert( room.occupants.insert(
participant2.resource.clone(), participant2.resource_str().to_string(),
Occupant::new(presence2.clone()).unwrap(), Occupant::new(presence2.clone()).unwrap(),
); );
let occupant3 = Occupant::new(presence3.clone()).unwrap(); let occupant3 = Occupant::new(presence3.clone()).unwrap();
room.occupants room.occupants
.insert(participant3.resource.clone(), occupant3.clone()); .insert(participant3.resource_str().to_string(), occupant3.clone());
let self_item = MucItem::try_from( let self_item = MucItem::try_from(
r#"<item xmlns="http://jabber.org/protocol/muc#user" affiliation="owner" role="moderator" jid="bar@qxx/foo"/>"# r#"<item xmlns="http://jabber.org/protocol/muc#user" affiliation="owner" role="moderator" jid="bar@qxx/foo"/>"#
@ -1049,7 +1053,7 @@ mod tests {
} }
// Sessions not joined to the room, even from the same barejid, should be rejected // Sessions not joined to the room, even from the same barejid, should be rejected
let louise_full3 = LOUISE_BARE.clone().with_resource("othernick"); let louise_full3 = LOUISE_BARE.clone().with_resource_str("othernick").unwrap();
let presence2 = PresenceFull::try_from( let presence2 = PresenceFull::try_from(
Presence::new(PresenceType::None) Presence::new(PresenceType::None)
.with_from(Jid::Full(louise_full3)) .with_from(Jid::Full(louise_full3))

View file

@ -15,7 +15,7 @@
use crate::component::TestComponent; use crate::component::TestComponent;
use crate::handlers::handle_stanza; use crate::handlers::handle_stanza;
use crate::room::Room; use crate::room::Room;
use crate::tests::templates::{COMPONENT_JID, LOUISE_FULL1, LOUISE_ROOM1_PART}; use crate::tests::templates::{COMPONENT_JID, LOUISE_FULL1, LOUISE_ROOM1_PART, ROOM1_BARE};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::str::FromStr; use std::str::FromStr;
@ -119,8 +119,8 @@ async fn self_ping_answer() {
#[tokio::test] #[tokio::test]
async fn self_ping_participant_non_existing() { async fn self_ping_participant_non_existing() {
let realjid1 = Jid::Full(FullJid::from_str("foo@bar/qxx").unwrap()); let realjid1 = Jid::Full(FullJid::from_str("foo@bar/qxx").unwrap());
let roomjid = COMPONENT_JID.clone().with_node("room"); let roomjid = ROOM1_BARE.clone();
let participant1 = roomjid.clone().with_resource("nick1"); let participant1 = roomjid.with_resource_str("nick1").unwrap();
let ping: Element = Iq { let ping: Element = Iq {
from: Some(realjid1.clone()), from: Some(realjid1.clone()),
@ -154,7 +154,7 @@ async fn self_ping_participant_non_existing() {
#[tokio::test] #[tokio::test]
async fn ping_room() { async fn ping_room() {
let realjid1 = Jid::Full(FullJid::from_str("foo@bar/qxx").unwrap()); let realjid1 = Jid::Full(FullJid::from_str("foo@bar/qxx").unwrap());
let roomjid = COMPONENT_JID.clone().with_node("room"); let roomjid = ROOM1_BARE.clone();
let ping: Element = Iq { let ping: Element = Iq {
from: Some(realjid1.clone()), from: Some(realjid1.clone()),

View file

@ -116,7 +116,7 @@ async fn join() {
assert_eq!(room.occupants.len(), 1); assert_eq!(room.occupants.len(), 1);
assert_eq!( assert_eq!(
room.occupants room.occupants
.get(&LOUISE_ROOM1_PART.resource) .get(LOUISE_ROOM1_PART.resource_str())
.unwrap() .unwrap()
.sessions .sessions
.len(), .len(),

View file

@ -17,6 +17,7 @@ use crate::occupant::Occupant;
use crate::presence::PresenceFull; use crate::presence::PresenceFull;
use crate::room::Room; use crate::room::Room;
use crate::session::Nick; use crate::session::Nick;
use jid::{DomainPart, NodePart};
use std::str::FromStr; use std::str::FromStr;
use std::sync::LazyLock; use std::sync::LazyLock;
use xmpp_parsers::{ use xmpp_parsers::{
@ -24,57 +25,61 @@ use xmpp_parsers::{
BareJid, FullJid, BareJid, FullJid,
}; };
const COMPONENT_DOMAIN_PART: LazyLock<DomainPart> =
LazyLock::new(|| DomainPart::new("commons.social").unwrap());
pub const COMPONENT_JID: LazyLock<BareJid> = pub const COMPONENT_JID: LazyLock<BareJid> =
LazyLock::new(|| BareJid::from_str("commons.social").unwrap()); LazyLock::new(|| BareJid::from_parts(None, &COMPONENT_DOMAIN_PART));
pub const ROOM1_BARE: LazyLock<BareJid> = pub const ROOM1_BARE: LazyLock<BareJid> = LazyLock::new(|| {
LazyLock::new(|| COMPONENT_JID.clone().with_node("direct-action")); let node = NodePart::new("direct-action").unwrap();
BareJid::from_parts(Some(&node), &COMPONENT_DOMAIN_PART)
});
/// https://en.wikipedia.org/wiki/Louise_Michel /// https://en.wikipedia.org/wiki/Louise_Michel
pub const LOUISE_BARE: LazyLock<BareJid> = pub const LOUISE_BARE: LazyLock<BareJid> =
LazyLock::new(|| BareJid::from_str("louise@example.net").unwrap()); LazyLock::new(|| BareJid::from_str("louise@example.net").unwrap());
pub const LOUISE_FULL1: LazyLock<FullJid> = pub const LOUISE_FULL1: LazyLock<FullJid> =
LazyLock::new(|| LOUISE_BARE.clone().with_resource("commune")); LazyLock::new(|| LOUISE_BARE.with_resource_str("commune").unwrap());
pub const LOUISE_FULL2: LazyLock<FullJid> = pub const LOUISE_FULL2: LazyLock<FullJid> =
LazyLock::new(|| LOUISE_BARE.clone().with_resource("desktop")); LazyLock::new(|| LOUISE_BARE.with_resource_str("desktop").unwrap());
pub const LOUISE_NICK: &'static str = "louise"; pub const LOUISE_NICK: &'static str = "louise";
pub const LOUISE_NICK2: &'static str = "louise_"; pub const LOUISE_NICK2: &'static str = "louise_";
pub const LOUISE_ROOM1_PART: LazyLock<FullJid> = pub const LOUISE_ROOM1_PART: LazyLock<FullJid> =
LazyLock::new(|| ROOM1_BARE.clone().with_resource(LOUISE_NICK)); LazyLock::new(|| ROOM1_BARE.with_resource_str(LOUISE_NICK).unwrap());
pub const LOUISE_ROOM1_PART2: LazyLock<FullJid> = pub const LOUISE_ROOM1_PART2: LazyLock<FullJid> =
LazyLock::new(|| ROOM1_BARE.clone().with_resource(LOUISE_NICK2)); LazyLock::new(|| ROOM1_BARE.with_resource_str(LOUISE_NICK2).unwrap());
/// https://en.wikipedia.org/wiki/Kanno_Sugako /// https://en.wikipedia.org/wiki/Kanno_Sugako
pub const SUGAKO_BARE: LazyLock<BareJid> = pub const SUGAKO_BARE: LazyLock<BareJid> =
LazyLock::new(|| BareJid::from_str("すがこ@example.net").unwrap()); LazyLock::new(|| BareJid::from_str("すがこ@example.net").unwrap());
pub const SUGAKO_FULL1: LazyLock<FullJid> = pub const SUGAKO_FULL1: LazyLock<FullJid> =
LazyLock::new(|| SUGAKO_BARE.clone().with_resource("desktop")); LazyLock::new(|| SUGAKO_BARE.with_resource_str("desktop").unwrap());
pub const SUGAKO_FULL2: LazyLock<FullJid> = pub const SUGAKO_FULL2: LazyLock<FullJid> =
LazyLock::new(|| SUGAKO_BARE.clone().with_resource("mobile")); LazyLock::new(|| SUGAKO_BARE.with_resource_str("mobile").unwrap());
pub const SUGAKO_NICK: &'static str = "すがこ"; pub const SUGAKO_NICK: &'static str = "すがこ";
pub const SUGAKO_ROOM1_PART: LazyLock<FullJid> = pub const SUGAKO_ROOM1_PART: LazyLock<FullJid> =
LazyLock::new(|| ROOM1_BARE.clone().with_resource(SUGAKO_NICK)); LazyLock::new(|| ROOM1_BARE.with_resource_str(SUGAKO_NICK).unwrap());
/// https://en.wikipedia.org/wiki/Rosa_Luxemburg /// https://en.wikipedia.org/wiki/Rosa_Luxemburg
pub const ROSA_BARE: LazyLock<BareJid> = pub const ROSA_BARE: LazyLock<BareJid> =
LazyLock::new(|| BareJid::from_str("rosa@example.net").unwrap()); LazyLock::new(|| BareJid::from_str("rosa@example.net").unwrap());
pub const ROSA_FULL1: LazyLock<FullJid> = pub const ROSA_FULL1: LazyLock<FullJid> =
LazyLock::new(|| ROSA_BARE.clone().with_resource("desktop")); LazyLock::new(|| ROSA_BARE.with_resource_str("desktop").unwrap());
pub const ROSA_FULL2: LazyLock<FullJid> = pub const ROSA_FULL2: LazyLock<FullJid> =
LazyLock::new(|| ROSA_BARE.clone().with_resource("mobile")); LazyLock::new(|| ROSA_BARE.with_resource_str("mobile").unwrap());
pub const ROSA_NICK: &'static str = "rosa"; pub const ROSA_NICK: &'static str = "rosa";
pub const ROSA_ROOM1_PART: LazyLock<FullJid> = pub const ROSA_ROOM1_PART: LazyLock<FullJid> =
LazyLock::new(|| ROOM1_BARE.clone().with_resource(ROSA_NICK)); LazyLock::new(|| ROOM1_BARE.with_resource_str(ROSA_NICK).unwrap());
/// https://en.wikipedia.org/wiki/Peter_Kropotkin /// https://en.wikipedia.org/wiki/Peter_Kropotkin
pub const PETER_BARE: LazyLock<BareJid> = pub const PETER_BARE: LazyLock<BareJid> =
LazyLock::new(|| BareJid::from_str("peter@example.net").unwrap()); LazyLock::new(|| BareJid::from_str("peter@example.net").unwrap());
pub const PETER_FULL1: LazyLock<FullJid> = pub const PETER_FULL1: LazyLock<FullJid> =
LazyLock::new(|| PETER_BARE.clone().with_resource("desktop")); LazyLock::new(|| PETER_BARE.with_resource_str("desktop").unwrap());
pub const PETER_FULL2: LazyLock<FullJid> = pub const PETER_FULL2: LazyLock<FullJid> =
LazyLock::new(|| PETER_BARE.clone().with_resource("mobile")); LazyLock::new(|| PETER_BARE.with_resource_str("mobile").unwrap());
pub const PETER_NICK: &'static str = "peter"; pub const PETER_NICK: &'static str = "peter";
pub const PETER_ROOM1_PART: LazyLock<FullJid> = pub const PETER_ROOM1_PART: LazyLock<FullJid> =
LazyLock::new(|| ROOM1_BARE.clone().with_resource(PETER_NICK)); LazyLock::new(|| ROOM1_BARE.with_resource_str(PETER_NICK).unwrap());
pub fn one_participant_room(roomjid: BareJid) -> Room { pub fn one_participant_room(roomjid: BareJid) -> Room {
let mut room = Room::new(roomjid.clone()); let mut room = Room::new(roomjid.clone());
@ -113,7 +118,7 @@ pub async fn new_room<N: Into<Nick>>(roomjid: BareJid, occupants: Vec<(N, Vec<Fu
let mut room = Room::new(roomjid.clone()); let mut room = Room::new(roomjid.clone());
for (nick, occupant) in occupants { for (nick, occupant) in occupants {
let nick: Nick = nick.into(); let nick: Nick = nick.into();
let participant = roomjid.clone().with_resource(nick.clone()); let participant = roomjid.with_resource_str(&nick).unwrap();
for session in occupant { for session in occupant {
let presence = PresenceFull::try_from( let presence = PresenceFull::try_from(