aboutsummaryrefslogtreecommitdiffstats
path: root/stanza/src/xep_0084
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-04-03 23:17:06 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-04-03 23:17:06 +0100
commit1af59efbb312b680b742bb84198c6ba18a79ec31 (patch)
treed024166e5520f3b83d25c1e0d48445bebe31534d /stanza/src/xep_0084
parent20969bd8b9789c08303265ec263e02b5225348e6 (diff)
downloadluz-1af59efbb312b680b742bb84198c6ba18a79ec31.tar.gz
luz-1af59efbb312b680b742bb84198c6ba18a79ec31.tar.bz2
luz-1af59efbb312b680b742bb84198c6ba18a79ec31.zip
feat(stanza): xep-0084: user avatar
Diffstat (limited to '')
-rw-r--r--stanza/src/xep_0084/data.rs30
-rw-r--r--stanza/src/xep_0084/metadata.rs106
-rw-r--r--stanza/src/xep_0084/mod.rs8
3 files changed, 144 insertions, 0 deletions
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;