session: Remove two FullJids from Session

They're already stored in the presence we own and we can get them for
free.

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-12-25 01:00:52 +01:00
parent 6e73112251
commit 65c7383745
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
4 changed files with 52 additions and 67 deletions

View file

@ -36,8 +36,10 @@ pub enum Error {
/// Raised whenever an operation is applied to a session which isn't the primary session, used
/// for Multi-Session Nick support.
SecondarySession(Session),
/// Raised when a JID was supposed to be present
MissingJid,
/// The origin (from) JID isn't of the expected for (bare or full)
InvalidOriginJid,
/// The destination (to) JID isn't of the expected for (bare or full)
InvalidDestinationJid,
/// Unhandled Iq with error description
UnhandledIq(String),
/// Jid Parse errors
@ -59,7 +61,8 @@ impl fmt::Display for Error {
Error::SessionAlreadyExists(err) => write!(f, "Session already exist: {:?}", err),
Error::ParticipantNotFound(err) => write!(f, "Participant not found: {}", err),
Error::SecondarySession(err) => write!(f, "Secondary session: {:?}", err),
Error::MissingJid => write!(f, "Missing JID"),
Error::InvalidOriginJid => write!(f, "Invalid origin JID"),
Error::InvalidDestinationJid => write!(f, "Invalid destination JID"),
Error::UnhandledIq(err) => write!(f, "Unhandled Iq: {:?}", err),
Error::Jid(err) => write!(f, "Jid Parse error: {}", err),
Error::Xmpp(err) => write!(f, "XMPP error: {}", err),

View file

@ -33,11 +33,12 @@ pub struct Occupant {
impl Occupant {
/// New occupant
pub fn new(presence: Presence) -> Result<Occupant, Error> {
let participant = presence.to.clone().map(FullJid::try_from).unwrap().unwrap();
let session = Session::try_from(presence)?;
Ok(Occupant {
real: BareJid::from(session.real.clone()),
participant: session.participant.clone(),
nick: session.participant.resource.clone(),
real: BareJid::from(session.real().clone()),
nick: participant.resource.clone(),
participant: participant,
sessions: vec![session],
})
}
@ -51,15 +52,15 @@ impl Occupant {
/// Add a new session to the occupant
pub fn add_session(&mut self, presence: Presence) -> Result<(), Error> {
let new_session = Session::try_from(presence)?;
if BareJid::from(new_session.real.clone()) != self.real {
if BareJid::from(new_session.real().clone()) != self.real {
return Err(Error::MismatchJids(
Jid::from(self.real.clone()),
Jid::from(new_session.real),
Jid::from(new_session.real().clone()),
));
}
for session in &self.sessions {
if &new_session.real == &session.real {
if new_session.real() == session.real() {
return Err(Error::SessionAlreadyExists(new_session));
}
}
@ -74,7 +75,7 @@ impl Occupant {
let len = self.sessions.len();
self.sessions
.retain(|session| session.real != own_session.real);
.retain(|session| session.real() != own_session.real());
// An item has been removed
if len != self.sessions.len() {
@ -86,7 +87,7 @@ impl Occupant {
/// Update session presence
pub fn update_presence(&mut self, presence: Presence) -> Result<(), Error> {
let own_session = Session::with_nick(presence, self.participant.resource.clone())?;
let own_session = Session::try_from(presence)?;
for (i, session) in self.sessions.iter().enumerate() {
if &own_session == session {
@ -175,7 +176,7 @@ mod tests {
.with_show(PresenceShow::Xa);
match occupant.update_presence(presence2.clone()) {
Err(Error::SecondarySession(session)) if session.real == *LOUISE_FULL2 => (),
Err(Error::SecondarySession(session)) if session.real() == &*LOUISE_FULL2 => (),
err => panic!(
"Should return Error::SecondarySession(Session {{ {:?} }}), returned: {:?}",
*LOUISE_FULL2, err,
@ -183,7 +184,7 @@ mod tests {
}
assert_eq!(
occupant.sessions[1],
Session::with_nick(presence2.clone(), LOUISE_NICK.clone()).unwrap()
Session::try_from(presence2.clone()).unwrap()
);
let presence_leave_louise2 = Presence::new(PresenceType::Unavailable)
@ -192,7 +193,7 @@ mod tests {
occupant.remove_session(presence_leave_louise2).unwrap();
match occupant.update_presence(presence2) {
Err(Error::NonexistantSession(session)) if session.real == *LOUISE_FULL2 => (),
Err(Error::NonexistantSession(session)) if session.real() == &*LOUISE_FULL2 => (),
err => panic!(
"Should return Error::SecondarySession(Session {{ {:?} }}), returned: {:?}",
*LOUISE_FULL2, err,

View file

@ -85,7 +85,7 @@ impl Room {
} else {
PresenceType::None
})
.with_to(Jid::Full(own_session.real.clone()))
.with_to(Jid::Full(own_session.real().clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
@ -98,7 +98,7 @@ impl Room {
} else {
PresenceType::None
})
.with_from(Jid::Full(own_session.participant.clone()))
.with_from(Jid::Full(own_occupant.participant.clone()))
.with_payloads(vec![MucUser {
status: Vec::new(),
items: vec![MucItem::new(
@ -124,7 +124,7 @@ impl Room {
// Send presence from participant to others.
for session in other.iter() {
// Skip sending if it's us.
if session.real == own_session.real {
if session.real() == own_session.real() {
continue;
}
// If own_session is leaving, and it is not the primary
@ -135,7 +135,7 @@ impl Room {
let presence = presence_to_old
.clone()
.with_to(Jid::Full(session.real.clone()));
.with_to(Jid::Full(session.real().clone()));
component.send_stanza(presence).await?;
}
}
@ -151,7 +151,7 @@ impl Room {
} else {
Role::Moderator
},
jid: Some(session.real.clone()),
jid: Some(session.real().clone()),
nick: None,
actor: None,
continue_: None,
@ -174,7 +174,7 @@ impl Room {
}
let presence = session_presence
.clone()
.with_to(Jid::Full(session.real.clone()))
.with_to(Jid::Full(session.real().clone()))
.with_payloads(vec![MucUser {
status: vec![],
items: self_items.clone(),
@ -192,7 +192,7 @@ impl Room {
PresenceType::None
})
.with_from(Jid::Full(own_occupant.participant.clone()))
.with_to(own_session.real.clone())
.with_to(own_session.real().clone())
.with_payloads(vec![MucUser {
status: if leave {
vec![MucStatus::SelfPresence]
@ -222,7 +222,7 @@ impl Room {
self.subject = Some((subject, setter, stamp));
}
let mut subject = Message::new(Some(Jid::Full(session.real)));
let mut subject = Message::new(Some(Jid::Full(session.real().clone())));
subject.from = Some(Jid::Full(
self.subject.as_ref().unwrap().1.participant.clone(),
));
@ -246,8 +246,8 @@ impl Room {
presence: Presence,
) -> Result<(), Error> {
let new_session = Session::try_from(presence)?;
let new_nick = new_session.participant.resource.clone();
let realjid = new_session.real.clone();
let new_nick = new_session.participant().resource.clone();
let realjid = new_session.real().clone();
// Ensure nick isn't already assigned
self.occupants.iter().try_for_each(|(nick, occupant)| {
@ -338,7 +338,7 @@ impl Room {
) -> Result<(), Error> {
let session = Session::try_from(presence)?;
// If occupant doesn't exist, ignore.
if let Some(mut occupant) = self.occupants.remove(&session.participant.resource) {
if let Some(mut occupant) = self.occupants.remove(&session.participant().resource) {
self.broadcast_presence(
component,
&occupant,
@ -347,11 +347,11 @@ impl Room {
)
.await?;
occupant.remove_session(session.presence)?;
occupant.remove_session(session.presence.clone())?;
if occupant.iter().len() > 0 {
let _ = self
.occupants
.insert(session.participant.resource.clone(), occupant);
.insert(session.participant().resource.clone(), occupant);
}
} else {
// TODO: Error
@ -363,15 +363,15 @@ impl Room {
/// Fetch the occupant associated with the provided nick and ensure the session is part of
/// it.
pub fn get_occupant(&self, session: &Session) -> Result<&Occupant, Error> {
if let Some(occupant) = self.occupants.get(&session.participant.resource) {
if occupant.contains(&session.real) {
if let Some(occupant) = self.occupants.get(&session.participant().resource) {
if occupant.contains(session.real()) {
Ok(occupant)
} else {
Err(Error::NonexistantSession(session.clone()))
}
} else {
Err(Error::ParticipantNotFound(
session.participant.resource.clone(),
session.participant().resource.clone(),
))
}
}
@ -379,15 +379,15 @@ impl Room {
/// Fetch a mutable reference of the occupant associated with the provided nick and ensure the
/// session is part of it.
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 occupant.contains(&session.real) {
if let Some(occupant) = self.occupants.get_mut(&session.participant().resource) {
if occupant.contains(session.real()) {
Ok(occupant)
} else {
Err(Error::NonexistantSession(session.clone()))
}
} else {
Err(Error::ParticipantNotFound(
session.participant.resource.clone(),
session.participant().resource.clone(),
))
}
}

View file

@ -15,7 +15,7 @@
use crate::error::Error;
use xmpp_parsers::{presence::Presence, BareJid, FullJid};
use xmpp_parsers::{presence::Presence, FullJid, Jid};
pub type Nick = String;
@ -23,8 +23,6 @@ pub type Nick = String;
#[derive(Debug, Clone)]
pub struct Session {
pub presence: Presence,
pub real: FullJid,
pub participant: FullJid,
}
impl Session {
@ -33,29 +31,24 @@ impl Session {
presence
}
/// Instanciate a Session from a presence which is adressed to the room JID.
pub fn with_nick<N: Into<Nick>>(presence: Presence, nick: N) -> Result<Session, Error> {
let presence = Session::filter_presence(presence);
Ok(Session {
real: presence
.from
.clone()
.map(FullJid::try_from)
.ok_or(Error::MissingJid)??,
participant: presence
.to
.clone()
.map(BareJid::from)
.ok_or(Error::MissingJid)?
.with_resource(nick.into()),
presence,
})
pub fn real(&self) -> &FullJid {
match &self.presence.from {
Some(Jid::Full(full)) => full,
_ => unreachable!(),
}
}
pub fn participant(&self) -> &FullJid {
match &self.presence.to {
Some(Jid::Full(full)) => full,
_ => unreachable!(),
}
}
}
impl PartialEq for Session {
fn eq(&self, other: &Session) -> bool {
self.real == other.real && self.participant == other.participant
self.real() == other.real() && self.participant() == other.participant()
}
}
@ -64,18 +57,6 @@ impl TryFrom<Presence> for Session {
fn try_from(presence: Presence) -> Result<Session, Error> {
let presence = Session::filter_presence(presence);
Ok(Session {
real: presence
.from
.clone()
.map(FullJid::try_from)
.ok_or(Error::MissingJid)??,
participant: presence
.to
.clone()
.map(FullJid::try_from)
.ok_or(Error::MissingJid)??,
presence,
})
Ok(Session { presence })
}
}