aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stanza/Cargo.toml1
-rw-r--r--stanza/src/client/message.rs12
-rw-r--r--stanza/src/lib.rs2
-rw-r--r--stanza/src/xep_0297.rs69
4 files changed, 84 insertions, 0 deletions
diff --git a/stanza/Cargo.toml b/stanza/Cargo.toml
index 884584a..ec68499 100644
--- a/stanza/Cargo.toml
+++ b/stanza/Cargo.toml
@@ -24,5 +24,6 @@ xep_0156 = ["dep:chrono"]
xep_0172 = []
xep_0199 = []
xep_0203 = ["dep:chrono"]
+xep_0297 = ["xep_0203"]
xep_0300 = []
xep_0390 = ["xep_0300"]
diff --git a/stanza/src/client/message.rs b/stanza/src/client/message.rs
index 41761d2..13ee6f1 100644
--- a/stanza/src/client/message.rs
+++ b/stanza/src/client/message.rs
@@ -11,6 +11,8 @@ use crate::xep_0131::Headers;
use crate::xep_0172::Nick;
#[cfg(feature = "xep_0203")]
use crate::xep_0203::Delay;
+#[cfg(feature = "xep_0297")]
+use crate::xep_0297::Forwarded;
use super::XMLNS;
@@ -34,6 +36,8 @@ pub struct Message {
pub nick: Option<Nick>,
#[cfg(feature = "xep_0060")]
pub event: Option<Event>,
+ #[cfg(feature = "xep_0297")]
+ pub forwarded: Option<Forwarded>,
}
impl FromElement for Message {
@@ -63,6 +67,9 @@ impl FromElement for Message {
#[cfg(feature = "xep_0060")]
let event = element.child_opt()?;
+ #[cfg(feature = "xep_0297")]
+ let forwarded = element.child_opt()?;
+
Ok(Message {
from,
id,
@@ -80,6 +87,8 @@ impl FromElement for Message {
nick,
#[cfg(feature = "xep_0060")]
event,
+ #[cfg(feature = "xep_0297")]
+ forwarded,
})
}
}
@@ -114,6 +123,9 @@ impl IntoElement for Message {
#[cfg(feature = "xep_0060")]
let builder = builder.push_child_opt(self.event.clone());
+ #[cfg(feature = "xep_0297")]
+ let builder = builder.push_child_opt(self.forwarded.clone());
+
builder
}
}
diff --git a/stanza/src/lib.rs b/stanza/src/lib.rs
index 8f8d430..8f9b788 100644
--- a/stanza/src/lib.rs
+++ b/stanza/src/lib.rs
@@ -33,6 +33,8 @@ pub mod xep_0172;
pub mod xep_0199;
#[cfg(feature = "xep_0203")]
pub mod xep_0203;
+#[cfg(feature = "xep_0297")]
+pub mod xep_0297;
#[cfg(feature = "xep_0300")]
pub mod xep_0300;
#[cfg(feature = "xep_0390")]
diff --git a/stanza/src/xep_0297.rs b/stanza/src/xep_0297.rs
new file mode 100644
index 0000000..4dc8a26
--- /dev/null
+++ b/stanza/src/xep_0297.rs
@@ -0,0 +1,69 @@
+use peanuts::{Element, FromElement, IntoElement};
+
+use crate::{
+ client::{self, iq::Iq, message::Message, presence::Presence},
+ xep_0203::Delay,
+};
+
+pub const XMLNS: &str = "urn:xmpp:forward:0";
+
+#[derive(Clone, Debug)]
+pub struct Forwarded {
+ delay: Option<Delay>,
+ stanza: Option<Box<Stanza>>,
+}
+
+impl FromElement for Forwarded {
+ fn from_element(mut element: Element) -> peanuts::DeserializeResult<Self> {
+ element.check_name("forwarded")?;
+ element.check_namespace(XMLNS)?;
+
+ let delay = element.pop_child_opt()?;
+ let stanza = element.pop_child_opt()?;
+ let stanza = stanza.map(|stanza| Box::new(stanza));
+
+ Ok(Self { delay, stanza })
+ }
+}
+
+impl IntoElement for Forwarded {
+ fn builder(&self) -> peanuts::ElementBuilder {
+ Element::builder("forwarded", Some(XMLNS))
+ .push_child_opt(self.delay.clone())
+ .push_child_opt(self.stanza.clone().map(|stanza| *stanza))
+ }
+}
+
+#[derive(Clone, Debug)]
+pub enum Stanza {
+ Message(Message),
+ Presence(Presence),
+ Iq(Iq),
+ // TODO: raw elements are received with reads.
+ // Raw(Element),
+}
+
+impl FromElement for Stanza {
+ fn from_element(element: Element) -> peanuts::DeserializeResult<Self> {
+ match element.identify() {
+ (Some(client::XMLNS), "message") => {
+ Ok(Stanza::Message(Message::from_element(element)?))
+ }
+ (Some(client::XMLNS), "presence") => {
+ Ok(Stanza::Presence(Presence::from_element(element)?))
+ }
+ (Some(client::XMLNS), "iq") => Ok(Stanza::Iq(Iq::from_element(element)?)),
+ _ => Err(peanuts::DeserializeError::UnexpectedElement(element)),
+ }
+ }
+}
+
+impl IntoElement for Stanza {
+ fn builder(&self) -> peanuts::ElementBuilder {
+ match self {
+ Stanza::Message(message) => message.builder(),
+ Stanza::Presence(presence) => presence.builder(),
+ Stanza::Iq(iq) => iq.builder(),
+ }
+ }
+}