diff --git a/src/main.rs b/src/main.rs
index ce35657..8f6cccb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -22,6 +22,7 @@ mod component;
mod error;
mod handlers;
mod occupant;
+mod presence;
mod room;
mod session;
diff --git a/src/presence.rs b/src/presence.rs
new file mode 100644
index 0000000..189eeed
--- /dev/null
+++ b/src/presence.rs
@@ -0,0 +1,46 @@
+// Copyright (C) 2022-2099 The crate authors.
+//
+// This program is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Affero General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+// for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+use crate::error::Error;
+use std::convert::TryFrom;
+use std::ops::Deref;
+use xmpp_parsers::{presence::Presence, Jid};
+
+/// Presence that has a FullJid as destination (to).
+#[derive(Debug, Clone, PartialEq)]
+pub struct PresenceFull(Presence);
+
+impl TryFrom for PresenceFull {
+ type Error = Error;
+
+ fn try_from(presence: Presence) -> Result {
+ match (&presence.from, &presence.to) {
+ (Some(Jid::Full(_)), Some(Jid::Full(_))) => (),
+ (Some(Jid::Full(_)), _) => return Err(Error::InvalidDestinationJid),
+ (_, Some(Jid::Full(_))) => return Err(Error::InvalidOriginJid),
+ _ => return Err(Error::InvalidOriginJid),
+ }
+
+ Ok(Self(presence))
+ }
+}
+
+impl Deref for PresenceFull {
+ type Target = Presence;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}