diff options
Diffstat (limited to 'stanza/src')
-rw-r--r-- | stanza/src/client/iq.rs | 13 | ||||
-rw-r--r-- | stanza/src/client/message.rs | 12 | ||||
-rw-r--r-- | stanza/src/lib.rs | 2 | ||||
-rw-r--r-- | stanza/src/xep_0060/event.rs | 28 | ||||
-rw-r--r-- | stanza/src/xep_0060/owner.rs | 4 | ||||
-rw-r--r-- | stanza/src/xep_0060/pubsub.rs | 18 | ||||
-rw-r--r-- | stanza/src/xep_0084/data.rs | 30 | ||||
-rw-r--r-- | stanza/src/xep_0084/metadata.rs | 106 | ||||
-rw-r--r-- | stanza/src/xep_0084/mod.rs | 8 |
9 files changed, 213 insertions, 8 deletions
diff --git a/stanza/src/client/iq.rs b/stanza/src/client/iq.rs index 50884aa..a1d58f6 100644 --- a/stanza/src/client/iq.rs +++ b/stanza/src/client/iq.rs @@ -18,7 +18,10 @@ use crate::roster; use crate::xep_0030::{self, info, items}; #[cfg(feature = "xep_0060")] -use crate::xep_0060::pubsub::{self, Pubsub}; +use crate::xep_0060::{ + self, + pubsub::{self, Pubsub}, +}; #[cfg(feature = "xep_0199")] use crate::xep_0199::{self, Ping}; @@ -47,6 +50,8 @@ pub enum Query { DiscoItems(items::Query), #[cfg(feature = "xep_0060")] Pubsub(Pubsub), + #[cfg(feature = "xep_0060")] + PubsubOwner(xep_0060::owner::Pubsub), #[cfg(feature = "xep_0199")] Ping(Ping), #[cfg(feature = "rfc_6121")] @@ -74,6 +79,10 @@ impl FromElement for Query { } #[cfg(feature = "xep_0060")] (Some(pubsub::XMLNS), "pubsub") => Ok(Query::Pubsub(Pubsub::from_element(element)?)), + #[cfg(feature = "xep_0060")] + (Some(xep_0060::owner::XMLNS), "pubsub") => Ok(Query::PubsubOwner( + xep_0060::owner::Pubsub::from_element(element)?, + )), _ => Ok(Query::Unsupported), } } @@ -95,6 +104,8 @@ impl IntoElement for Query { Query::DiscoItems(query) => query.builder(), #[cfg(feature = "xep_0060")] Query::Pubsub(pubsub) => pubsub.builder(), + #[cfg(feature = "xep_0060")] + Query::PubsubOwner(pubsub) => pubsub.builder(), } } } diff --git a/stanza/src/client/message.rs b/stanza/src/client/message.rs index d94b82e..78258ca 100644 --- a/stanza/src/client/message.rs +++ b/stanza/src/client/message.rs @@ -6,6 +6,8 @@ use peanuts::{ DeserializeError, Element, XML_NS, }; +#[cfg(feature = "xep_0060")] +use crate::xep_0060::event::Event; #[cfg(feature = "xep_0131")] use crate::xep_0131::Headers; #[cfg(feature = "xep_0172")] @@ -33,6 +35,8 @@ pub struct Message { pub headers: Option<Headers>, #[cfg(feature = "xep_0172")] pub nick: Option<Nick>, + #[cfg(feature = "xep_0060")] + pub event: Option<Event>, } impl FromElement for Message { @@ -59,6 +63,9 @@ impl FromElement for Message { #[cfg(feature = "xep_0172")] let nick = element.child_opt()?; + #[cfg(feature = "xep_0060")] + let event = element.child_opt()?; + Ok(Message { from, id, @@ -74,6 +81,8 @@ impl FromElement for Message { headers, #[cfg(feature = "xep_0172")] nick, + #[cfg(feature = "xep_0060")] + event, }) } } @@ -105,6 +114,9 @@ impl IntoElement for Message { #[cfg(feature = "xep_0172")] let builder = builder.push_child_opt(self.nick.clone()); + #[cfg(feature = "xep_0060")] + let builder = builder.push_child_opt(self.event.clone()); + builder } } diff --git a/stanza/src/lib.rs b/stanza/src/lib.rs index 3ecace0..569b891 100644 --- a/stanza/src/lib.rs +++ b/stanza/src/lib.rs @@ -17,6 +17,8 @@ pub mod xep_0030; pub mod xep_0059; #[cfg(feature = "xep_0060")] pub mod xep_0060; +#[cfg(feature = "xep_0084")] +pub mod xep_0084; #[cfg(feature = "xep_0115")] pub mod xep_0115; #[cfg(feature = "xep_0131")] diff --git a/stanza/src/xep_0060/event.rs b/stanza/src/xep_0060/event.rs index d2c150a..1be011d 100644 --- a/stanza/src/xep_0060/event.rs +++ b/stanza/src/xep_0060/event.rs @@ -8,6 +8,8 @@ use peanuts::{ }; use crate::xep_0004::X; +#[cfg(feature = "xep_0084")] +use crate::xep_0084; #[cfg(feature = "xep_0172")] use crate::xep_0172::{self, Nick}; @@ -219,8 +221,8 @@ impl IntoElement for Delete { #[derive(Clone, Debug)] pub struct Items { - node: String, - items: ItemsType, + pub node: String, + pub items: ItemsType, } impl FromElement for Items { @@ -260,9 +262,9 @@ pub enum ItemsType { #[derive(Clone, Debug)] pub struct Item { - id: Option<String>, - publisher: Option<String>, - item: Option<Content>, + pub id: Option<String>, + pub publisher: Option<String>, + pub item: Option<Content>, } impl FromElement for Item { @@ -296,6 +298,10 @@ impl IntoElement for Item { pub enum Content { #[cfg(feature = "xep_0172")] Nick(Nick), + #[cfg(feature = "xep_0084")] + AvatarData(xep_0084::Data), + #[cfg(feature = "xep_0084")] + AvatarMetadata(xep_0084::Metadata), Unknown(Element), } @@ -304,6 +310,14 @@ impl FromElement for Content { match element.identify() { #[cfg(feature = "xep_0172")] (Some(xep_0172::XMLNS), "nick") => Ok(Content::Nick(Nick::from_element(element)?)), + #[cfg(feature = "xep_0084")] + (Some(xep_0084::data::XMLNS), "data") => { + Ok(Content::AvatarData(xep_0084::Data::from_element(element)?)) + } + #[cfg(feature = "xep_0084")] + (Some(xep_0084::metadata::XMLNS), "metadata") => Ok(Content::AvatarMetadata( + xep_0084::Metadata::from_element(element)?, + )), _ => Ok(Self::Unknown(element)), } } @@ -314,6 +328,10 @@ impl IntoElement for Content { match self { #[cfg(feature = "xep_0172")] Content::Nick(nick) => nick.builder(), + #[cfg(feature = "xep_0084")] + Content::AvatarData(data) => data.builder(), + #[cfg(feature = "xep_0084")] + Content::AvatarMetadata(metadata) => metadata.builder(), Content::Unknown(_e) => panic!("unknown content cannot be serialized"), } } diff --git a/stanza/src/xep_0060/owner.rs b/stanza/src/xep_0060/owner.rs index 1fedc60..7cf4355 100644 --- a/stanza/src/xep_0060/owner.rs +++ b/stanza/src/xep_0060/owner.rs @@ -198,8 +198,8 @@ impl IntoElement for Default { #[derive(Clone, Debug)] pub struct Delete { - node: String, - redirect: Option<Redirect>, + pub node: String, + pub redirect: Option<Redirect>, } impl FromElement for Delete { diff --git a/stanza/src/xep_0060/pubsub.rs b/stanza/src/xep_0060/pubsub.rs index 25fc405..0f698dc 100644 --- a/stanza/src/xep_0060/pubsub.rs +++ b/stanza/src/xep_0060/pubsub.rs @@ -7,6 +7,8 @@ use peanuts::{ }; use crate::xep_0004::X; +#[cfg(feature = "xep_0084")] +use crate::xep_0084; #[cfg(feature = "xep_0172")] use crate::xep_0172::{self, Nick}; @@ -377,6 +379,10 @@ impl IntoElement for Item { pub enum Content { #[cfg(feature = "xep_0172")] Nick(Nick), + #[cfg(feature = "xep_0084")] + AvatarData(xep_0084::Data), + #[cfg(feature = "xep_0084")] + AvatarMetadata(xep_0084::Metadata), Unknown(Element), } @@ -385,6 +391,14 @@ impl FromElement for Content { match element.identify() { #[cfg(feature = "xep_0172")] (Some(xep_0172::XMLNS), "nick") => Ok(Content::Nick(Nick::from_element(element)?)), + #[cfg(feature = "xep_0084")] + (Some(xep_0084::data::XMLNS), "data") => { + Ok(Content::AvatarData(xep_0084::Data::from_element(element)?)) + } + #[cfg(feature = "xep_0084")] + (Some(xep_0084::metadata::XMLNS), "metadata") => Ok(Content::AvatarMetadata( + xep_0084::Metadata::from_element(element)?, + )), _ => Ok(Self::Unknown(element)), } } @@ -395,6 +409,10 @@ impl IntoElement for Content { match self { #[cfg(feature = "xep_0172")] Content::Nick(nick) => nick.builder(), + #[cfg(feature = "xep_0084")] + Content::AvatarData(data) => data.builder(), + #[cfg(feature = "xep_0084")] + Content::AvatarMetadata(metadata) => metadata.builder(), Content::Unknown(_e) => panic!("unknown content cannot be serialized"), } } diff --git a/stanza/src/xep_0084/data.rs b/stanza/src/xep_0084/data.rs new file mode 100644 index 0000000..2a37df4 --- /dev/null +++ b/stanza/src/xep_0084/data.rs @@ -0,0 +1,30 @@ +use peanuts::{ + element::{FromElement, IntoElement}, + Element, +}; + +pub const XMLNS: &str = "urn:xmpp:avatar:data"; + +#[derive(Debug, Clone)] +pub struct Data(pub String); + +impl FromElement for Data { + fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("data")?; + element.check_namespace(XMLNS)?; + + Ok(Self(element.pop_value_opt()?.unwrap_or_default())) + } +} + +impl IntoElement for Data { + fn builder(&self) -> peanuts::element::ElementBuilder { + let builder = Element::builder("data", Some(XMLNS)); + + if self.0.is_empty() { + builder + } else { + builder.push_text(self.0.clone()) + } + } +} diff --git a/stanza/src/xep_0084/metadata.rs b/stanza/src/xep_0084/metadata.rs new file mode 100644 index 0000000..c6a3fb4 --- /dev/null +++ b/stanza/src/xep_0084/metadata.rs @@ -0,0 +1,106 @@ +use peanuts::{ + element::{FromElement, IntoElement}, + Element, +}; + +pub const XMLNS: &str = "urn:xmpp:avatar:metadata"; + +#[derive(Debug, Clone)] +pub struct Metadata { + pub info: Vec<Info>, + pub pointers: Vec<Pointer>, +} + +impl FromElement for Metadata { + fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("metadata")?; + element.check_namespace(XMLNS)?; + + let info = element.pop_children()?; + let pointers = element.pop_children()?; + + Ok(Self { info, pointers }) + } +} + +impl IntoElement for Metadata { + fn builder(&self) -> peanuts::element::ElementBuilder { + Element::builder("metadata", Some(XMLNS)) + .push_children(self.info.clone()) + .push_children(self.pointers.clone()) + } +} + +#[derive(Debug, Clone)] +pub struct Info { + pub bytes: u32, + pub height: Option<u16>, + pub id: String, + pub r#type: String, + pub url: Option<String>, + pub width: Option<u16>, +} + +impl FromElement for Info { + fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("info")?; + element.check_namespace(XMLNS)?; + + let bytes = element.attribute("bytes")?; + let height = element.attribute_opt("height")?; + let id = element.attribute("id")?; + let r#type = element.attribute("type")?; + let url = element.attribute_opt("url")?; + let width = element.attribute_opt("width")?; + + Ok(Self { + bytes, + height, + id, + r#type, + url, + width, + }) + } +} + +impl IntoElement for Info { + fn builder(&self) -> peanuts::element::ElementBuilder { + Element::builder("info", Some(XMLNS)) + .push_attribute("bytes", self.bytes) + .push_attribute_opt("height", self.height) + .push_attribute("id", self.id.clone()) + .push_attribute("type", self.r#type.clone()) + .push_attribute_opt("url", self.url.clone()) + .push_attribute_opt("width", self.width) + } +} + +#[derive(Debug, Clone)] +pub struct Pointer(pub PointerInner); + +impl FromElement for Pointer { + fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("pointer")?; + element.check_namespace(XMLNS)?; + + Ok(Self(PointerInner::Unsupported(element.pop_child_one()?))) + } +} + +impl IntoElement for Pointer { + fn builder(&self) -> peanuts::element::ElementBuilder { + let _builder = Element::builder("pointer", Some(XMLNS)); + + match &self.0 { + PointerInner::Unsupported(_element) => { + panic!("cannot serialize unsupported PointerInner") + } + } + } +} + +#[derive(Debug, Clone)] +pub enum PointerInner { + Unsupported(Element), +} diff --git a/stanza/src/xep_0084/mod.rs b/stanza/src/xep_0084/mod.rs new file mode 100644 index 0000000..be7d5d7 --- /dev/null +++ b/stanza/src/xep_0084/mod.rs @@ -0,0 +1,8 @@ +pub use data::Data; +pub use metadata::Info; +pub use metadata::Metadata; +pub use metadata::Pointer; +pub use metadata::PointerInner; + +pub mod data; +pub mod metadata; |