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
|
/// Raised whenever an operation is applied to a session which isn't the primary session, used
|
||||||
/// for Multi-Session Nick support.
|
/// for Multi-Session Nick support.
|
||||||
SecondarySession(Session),
|
SecondarySession(Session),
|
||||||
/// Raised when a JID was supposed to be present
|
/// The origin (from) JID isn't of the expected for (bare or full)
|
||||||
MissingJid,
|
InvalidOriginJid,
|
||||||
|
/// The destination (to) JID isn't of the expected for (bare or full)
|
||||||
|
InvalidDestinationJid,
|
||||||
/// Unhandled Iq with error description
|
/// Unhandled Iq with error description
|
||||||
UnhandledIq(String),
|
UnhandledIq(String),
|
||||||
/// Jid Parse errors
|
/// Jid Parse errors
|
||||||
|
@ -59,7 +61,8 @@ impl fmt::Display for Error {
|
||||||
Error::SessionAlreadyExists(err) => write!(f, "Session already exist: {:?}", err),
|
Error::SessionAlreadyExists(err) => write!(f, "Session already exist: {:?}", err),
|
||||||
Error::ParticipantNotFound(err) => write!(f, "Participant not found: {}", err),
|
Error::ParticipantNotFound(err) => write!(f, "Participant not found: {}", err),
|
||||||
Error::SecondarySession(err) => write!(f, "Secondary session: {:?}", 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::UnhandledIq(err) => write!(f, "Unhandled Iq: {:?}", err),
|
||||||
Error::Jid(err) => write!(f, "Jid Parse error: {}", err),
|
Error::Jid(err) => write!(f, "Jid Parse error: {}", err),
|
||||||
Error::Xmpp(err) => write!(f, "XMPP error: {}", err),
|
Error::Xmpp(err) => write!(f, "XMPP error: {}", err),
|
||||||
|
|
|
@ -33,11 +33,12 @@ pub struct Occupant {
|
||||||
impl Occupant {
|
impl Occupant {
|
||||||
/// New occupant
|
/// New occupant
|
||||||
pub fn new(presence: Presence) -> Result<Occupant, Error> {
|
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)?;
|
let session = Session::try_from(presence)?;
|
||||||
Ok(Occupant {
|
Ok(Occupant {
|
||||||
real: BareJid::from(session.real.clone()),
|
real: BareJid::from(session.real().clone()),
|
||||||
participant: session.participant.clone(),
|
nick: participant.resource.clone(),
|
||||||
nick: session.participant.resource.clone(),
|
participant: participant,
|
||||||
sessions: vec![session],
|
sessions: vec![session],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -51,15 +52,15 @@ impl Occupant {
|
||||||
/// Add a new session to the occupant
|
/// Add a new session to the occupant
|
||||||
pub fn add_session(&mut self, presence: Presence) -> Result<(), Error> {
|
pub fn add_session(&mut self, presence: Presence) -> 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().clone()) != 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),
|
Jid::from(new_session.real().clone()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for session in &self.sessions {
|
for session in &self.sessions {
|
||||||
if &new_session.real == &session.real {
|
if new_session.real() == session.real() {
|
||||||
return Err(Error::SessionAlreadyExists(new_session));
|
return Err(Error::SessionAlreadyExists(new_session));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +75,7 @@ impl Occupant {
|
||||||
|
|
||||||
let len = self.sessions.len();
|
let len = self.sessions.len();
|
||||||
self.sessions
|
self.sessions
|
||||||
.retain(|session| session.real != own_session.real);
|
.retain(|session| session.real() != own_session.real());
|
||||||
|
|
||||||
// An item has been removed
|
// An item has been removed
|
||||||
if len != self.sessions.len() {
|
if len != self.sessions.len() {
|
||||||
|
@ -86,7 +87,7 @@ impl Occupant {
|
||||||
|
|
||||||
/// Update session presence
|
/// Update session presence
|
||||||
pub fn update_presence(&mut self, presence: Presence) -> Result<(), Error> {
|
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() {
|
for (i, session) in self.sessions.iter().enumerate() {
|
||||||
if &own_session == session {
|
if &own_session == session {
|
||||||
|
@ -175,7 +176,7 @@ mod tests {
|
||||||
.with_show(PresenceShow::Xa);
|
.with_show(PresenceShow::Xa);
|
||||||
|
|
||||||
match occupant.update_presence(presence2.clone()) {
|
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!(
|
err => panic!(
|
||||||
"Should return Error::SecondarySession(Session {{ {:?} }}), returned: {:?}",
|
"Should return Error::SecondarySession(Session {{ {:?} }}), returned: {:?}",
|
||||||
*LOUISE_FULL2, err,
|
*LOUISE_FULL2, err,
|
||||||
|
@ -183,7 +184,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
occupant.sessions[1],
|
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)
|
let presence_leave_louise2 = Presence::new(PresenceType::Unavailable)
|
||||||
|
@ -192,7 +193,7 @@ mod tests {
|
||||||
occupant.remove_session(presence_leave_louise2).unwrap();
|
occupant.remove_session(presence_leave_louise2).unwrap();
|
||||||
|
|
||||||
match occupant.update_presence(presence2) {
|
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!(
|
err => panic!(
|
||||||
"Should return Error::SecondarySession(Session {{ {:?} }}), returned: {:?}",
|
"Should return Error::SecondarySession(Session {{ {:?} }}), returned: {:?}",
|
||||||
*LOUISE_FULL2, err,
|
*LOUISE_FULL2, err,
|
||||||
|
|
38
src/room.rs
38
src/room.rs
|
@ -85,7 +85,7 @@ impl Room {
|
||||||
} else {
|
} else {
|
||||||
PresenceType::None
|
PresenceType::None
|
||||||
})
|
})
|
||||||
.with_to(Jid::Full(own_session.real.clone()))
|
.with_to(Jid::Full(own_session.real().clone()))
|
||||||
.with_payloads(vec![MucUser {
|
.with_payloads(vec![MucUser {
|
||||||
status: Vec::new(),
|
status: Vec::new(),
|
||||||
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
|
items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)],
|
||||||
|
@ -98,7 +98,7 @@ impl Room {
|
||||||
} else {
|
} else {
|
||||||
PresenceType::None
|
PresenceType::None
|
||||||
})
|
})
|
||||||
.with_from(Jid::Full(own_session.participant.clone()))
|
.with_from(Jid::Full(own_occupant.participant.clone()))
|
||||||
.with_payloads(vec![MucUser {
|
.with_payloads(vec![MucUser {
|
||||||
status: Vec::new(),
|
status: Vec::new(),
|
||||||
items: vec![MucItem::new(
|
items: vec![MucItem::new(
|
||||||
|
@ -124,7 +124,7 @@ impl Room {
|
||||||
// Send presence from participant to others.
|
// Send presence from participant to others.
|
||||||
for session in other.iter() {
|
for session in other.iter() {
|
||||||
// Skip sending if it's us.
|
// Skip sending if it's us.
|
||||||
if session.real == own_session.real {
|
if session.real() == own_session.real() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If own_session is leaving, and it is not the primary
|
// If own_session is leaving, and it is not the primary
|
||||||
|
@ -135,7 +135,7 @@ impl Room {
|
||||||
|
|
||||||
let presence = presence_to_old
|
let presence = presence_to_old
|
||||||
.clone()
|
.clone()
|
||||||
.with_to(Jid::Full(session.real.clone()));
|
.with_to(Jid::Full(session.real().clone()));
|
||||||
component.send_stanza(presence).await?;
|
component.send_stanza(presence).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ impl Room {
|
||||||
} else {
|
} else {
|
||||||
Role::Moderator
|
Role::Moderator
|
||||||
},
|
},
|
||||||
jid: Some(session.real.clone()),
|
jid: Some(session.real().clone()),
|
||||||
nick: None,
|
nick: None,
|
||||||
actor: None,
|
actor: None,
|
||||||
continue_: None,
|
continue_: None,
|
||||||
|
@ -174,7 +174,7 @@ impl Room {
|
||||||
}
|
}
|
||||||
let presence = session_presence
|
let presence = session_presence
|
||||||
.clone()
|
.clone()
|
||||||
.with_to(Jid::Full(session.real.clone()))
|
.with_to(Jid::Full(session.real().clone()))
|
||||||
.with_payloads(vec![MucUser {
|
.with_payloads(vec![MucUser {
|
||||||
status: vec![],
|
status: vec![],
|
||||||
items: self_items.clone(),
|
items: self_items.clone(),
|
||||||
|
@ -192,7 +192,7 @@ impl Room {
|
||||||
PresenceType::None
|
PresenceType::None
|
||||||
})
|
})
|
||||||
.with_from(Jid::Full(own_occupant.participant.clone()))
|
.with_from(Jid::Full(own_occupant.participant.clone()))
|
||||||
.with_to(own_session.real.clone())
|
.with_to(own_session.real().clone())
|
||||||
.with_payloads(vec![MucUser {
|
.with_payloads(vec![MucUser {
|
||||||
status: if leave {
|
status: if leave {
|
||||||
vec![MucStatus::SelfPresence]
|
vec![MucStatus::SelfPresence]
|
||||||
|
@ -222,7 +222,7 @@ impl Room {
|
||||||
self.subject = Some((subject, setter, stamp));
|
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(
|
subject.from = Some(Jid::Full(
|
||||||
self.subject.as_ref().unwrap().1.participant.clone(),
|
self.subject.as_ref().unwrap().1.participant.clone(),
|
||||||
));
|
));
|
||||||
|
@ -246,8 +246,8 @@ impl Room {
|
||||||
presence: Presence,
|
presence: Presence,
|
||||||
) -> 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.clone();
|
||||||
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)| {
|
||||||
|
@ -338,7 +338,7 @@ 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) {
|
if let Some(mut occupant) = self.occupants.remove(&session.participant().resource) {
|
||||||
self.broadcast_presence(
|
self.broadcast_presence(
|
||||||
component,
|
component,
|
||||||
&occupant,
|
&occupant,
|
||||||
|
@ -347,11 +347,11 @@ impl Room {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
occupant.remove_session(session.presence)?;
|
occupant.remove_session(session.presence.clone())?;
|
||||||
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.clone(), occupant);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: Error
|
// TODO: Error
|
||||||
|
@ -363,15 +363,15 @@ impl Room {
|
||||||
/// Fetch the occupant associated with the provided nick and ensure the session is part of
|
/// Fetch the occupant associated with the provided nick and ensure the session is part of
|
||||||
/// it.
|
/// it.
|
||||||
pub fn get_occupant(&self, session: &Session) -> Result<&Occupant, Error> {
|
pub fn get_occupant(&self, session: &Session) -> Result<&Occupant, Error> {
|
||||||
if let Some(occupant) = self.occupants.get(&session.participant.resource) {
|
if let Some(occupant) = self.occupants.get(&session.participant().resource) {
|
||||||
if occupant.contains(&session.real) {
|
if occupant.contains(session.real()) {
|
||||||
Ok(occupant)
|
Ok(occupant)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NonexistantSession(session.clone()))
|
Err(Error::NonexistantSession(session.clone()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ParticipantNotFound(
|
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
|
/// Fetch a mutable reference of the occupant associated with the provided nick and ensure the
|
||||||
/// session is part of it.
|
/// session is part of it.
|
||||||
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) {
|
||||||
if occupant.contains(&session.real) {
|
if occupant.contains(session.real()) {
|
||||||
Ok(occupant)
|
Ok(occupant)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NonexistantSession(session.clone()))
|
Err(Error::NonexistantSession(session.clone()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ParticipantNotFound(
|
Err(Error::ParticipantNotFound(
|
||||||
session.participant.resource.clone(),
|
session.participant().resource.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
use xmpp_parsers::{presence::Presence, BareJid, FullJid};
|
use xmpp_parsers::{presence::Presence, FullJid, Jid};
|
||||||
|
|
||||||
pub type Nick = String;
|
pub type Nick = String;
|
||||||
|
|
||||||
|
@ -23,8 +23,6 @@ pub type Nick = String;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
pub presence: Presence,
|
pub presence: Presence,
|
||||||
pub real: FullJid,
|
|
||||||
pub participant: FullJid,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Session {
|
impl Session {
|
||||||
|
@ -33,29 +31,24 @@ impl Session {
|
||||||
presence
|
presence
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instanciate a Session from a presence which is adressed to the room JID.
|
pub fn real(&self) -> &FullJid {
|
||||||
pub fn with_nick<N: Into<Nick>>(presence: Presence, nick: N) -> Result<Session, Error> {
|
match &self.presence.from {
|
||||||
let presence = Session::filter_presence(presence);
|
Some(Jid::Full(full)) => full,
|
||||||
Ok(Session {
|
_ => unreachable!(),
|
||||||
real: presence
|
}
|
||||||
.from
|
}
|
||||||
.clone()
|
|
||||||
.map(FullJid::try_from)
|
pub fn participant(&self) -> &FullJid {
|
||||||
.ok_or(Error::MissingJid)??,
|
match &self.presence.to {
|
||||||
participant: presence
|
Some(Jid::Full(full)) => full,
|
||||||
.to
|
_ => unreachable!(),
|
||||||
.clone()
|
}
|
||||||
.map(BareJid::from)
|
|
||||||
.ok_or(Error::MissingJid)?
|
|
||||||
.with_resource(nick.into()),
|
|
||||||
presence,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Session {
|
impl PartialEq for Session {
|
||||||
fn eq(&self, other: &Session) -> bool {
|
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> {
|
fn try_from(presence: Presence) -> Result<Session, Error> {
|
||||||
let presence = Session::filter_presence(presence);
|
let presence = Session::filter_presence(presence);
|
||||||
Ok(Session {
|
Ok(Session { presence })
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue