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, stanza: Option>, } impl FromElement for Forwarded { fn from_element(mut element: Element) -> peanuts::DeserializeResult { 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 { 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(), } } }