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:
parent
6e73112251
commit
65c7383745
4 changed files with 52 additions and 67 deletions
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
38
src/room.rs
38
src/room.rs
|
@ -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(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue