diff options
| author | 2024-12-04 18:18:37 +0000 | |
|---|---|---|
| committer | 2024-12-04 18:18:37 +0000 | |
| commit | 1b91ff690488b65b552c90bd5392b9a300c8c981 (patch) | |
| tree | 9c290f69b26eba0393d7bbc05ba29c28ea74a26e /src/stanza | |
| parent | 03764f8cedb3f0a55a61be0f0a59faaa6357a83a (diff) | |
| download | luz-1b91ff690488b65b552c90bd5392b9a300c8c981.tar.gz luz-1b91ff690488b65b552c90bd5392b9a300c8c981.tar.bz2 luz-1b91ff690488b65b552c90bd5392b9a300c8c981.zip | |
use cargo workspace
Diffstat (limited to 'src/stanza')
| -rw-r--r-- | src/stanza/bind.rs | 99 | ||||
| -rw-r--r-- | src/stanza/client/error.rs | 83 | ||||
| -rw-r--r-- | src/stanza/client/iq.rs | 124 | ||||
| -rw-r--r-- | src/stanza/client/message.rs | 186 | ||||
| -rw-r--r-- | src/stanza/client/mod.rs | 61 | ||||
| -rw-r--r-- | src/stanza/client/presence.rs | 226 | ||||
| -rw-r--r-- | src/stanza/mod.rs | 11 | ||||
| -rw-r--r-- | src/stanza/sasl.rs | 246 | ||||
| -rw-r--r-- | src/stanza/stanza_error.rs | 126 | ||||
| -rw-r--r-- | src/stanza/starttls.rs | 94 | ||||
| -rw-r--r-- | src/stanza/stream.rs | 191 | ||||
| -rw-r--r-- | src/stanza/stream_error.rs | 137 | 
12 files changed, 0 insertions, 1584 deletions
| diff --git a/src/stanza/bind.rs b/src/stanza/bind.rs deleted file mode 100644 index 0e67a83..0000000 --- a/src/stanza/bind.rs +++ /dev/null @@ -1,99 +0,0 @@ -use peanuts::{ -    element::{FromElement, IntoElement}, -    Element, -}; - -use crate::JID; - -pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-bind"; - -#[derive(Clone)] -pub struct Bind { -    pub r#type: Option<BindType>, -} - -impl FromElement for Bind { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("bind"); -        element.check_name(XMLNS); - -        let r#type = element.pop_child_opt()?; - -        Ok(Bind { r#type }) -    } -} - -impl IntoElement for Bind { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("bind", Some(XMLNS)).push_child_opt(self.r#type.clone()) -    } -} - -#[derive(Clone)] -pub enum BindType { -    Resource(ResourceType), -    Jid(FullJidType), -} - -impl FromElement for BindType { -    fn from_element(element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        match element.identify() { -            (Some(XMLNS), "resource") => { -                Ok(BindType::Resource(ResourceType::from_element(element)?)) -            } -            (Some(XMLNS), "jid") => Ok(BindType::Jid(FullJidType::from_element(element)?)), -            _ => Err(peanuts::DeserializeError::UnexpectedElement(element)), -        } -    } -} - -impl IntoElement for BindType { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        match self { -            BindType::Resource(resource_type) => resource_type.builder(), -            BindType::Jid(full_jid_type) => full_jid_type.builder(), -        } -    } -} - -// minLength 8 maxLength 3071 -#[derive(Clone)] -pub struct FullJidType(pub JID); - -impl FromElement for FullJidType { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("jid"); -        element.check_namespace(XMLNS); - -        let jid = element.pop_value()?; - -        Ok(FullJidType(jid)) -    } -} - -impl IntoElement for FullJidType { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("jid", Some(XMLNS)).push_text(self.0.clone()) -    } -} - -// minLength 1 maxLength 1023 -#[derive(Clone)] -pub struct ResourceType(pub String); - -impl FromElement for ResourceType { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("resource")?; -        element.check_namespace(XMLNS)?; - -        let resource = element.pop_value()?; - -        Ok(ResourceType(resource)) -    } -} - -impl IntoElement for ResourceType { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("resource", Some(XMLNS)).push_text(self.0.clone()) -    } -} diff --git a/src/stanza/client/error.rs b/src/stanza/client/error.rs deleted file mode 100644 index 545b9a7..0000000 --- a/src/stanza/client/error.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::str::FromStr; - -use peanuts::element::{FromElement, IntoElement}; -use peanuts::{DeserializeError, Element}; - -use crate::stanza::stanza_error::Error as StanzaError; -use crate::stanza::stanza_error::Text; - -use super::XMLNS; - -#[derive(Clone, Debug)] -pub struct Error { -    by: Option<String>, -    r#type: ErrorType, -    // children (sequence) -    error: StanzaError, -    text: Option<Text>, -} - -impl FromElement for Error { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("error")?; -        element.check_name(XMLNS)?; - -        let by = element.attribute_opt("by")?; -        let r#type = element.attribute("type")?; -        let error = element.pop_child_one()?; -        let text = element.pop_child_opt()?; - -        Ok(Error { -            by, -            r#type, -            error, -            text, -        }) -    } -} - -impl IntoElement for Error { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("error", Some(XMLNS)) -            .push_attribute_opt("by", self.by.clone()) -            .push_attribute("type", self.r#type) -            .push_child(self.error.clone()) -            .push_child_opt(self.text.clone()) -    } -} - -#[derive(Copy, Clone, Debug)] -pub enum ErrorType { -    Auth, -    Cancel, -    Continue, -    Modify, -    Wait, -} - -impl FromStr for ErrorType { -    type Err = DeserializeError; - -    fn from_str(s: &str) -> Result<Self, Self::Err> { -        match s { -            "auth" => Ok(ErrorType::Auth), -            "cancel" => Ok(ErrorType::Cancel), -            "continue" => Ok(ErrorType::Continue), -            "modify" => Ok(ErrorType::Modify), -            "wait" => Ok(ErrorType::Wait), -            _ => Err(DeserializeError::FromStr(s.to_string())), -        } -    } -} - -impl ToString for ErrorType { -    fn to_string(&self) -> String { -        match self { -            ErrorType::Auth => "auth".to_string(), -            ErrorType::Cancel => "cancel".to_string(), -            ErrorType::Continue => "continue".to_string(), -            ErrorType::Modify => "modify".to_string(), -            ErrorType::Wait => "wait".to_string(), -        } -    } -} diff --git a/src/stanza/client/iq.rs b/src/stanza/client/iq.rs deleted file mode 100644 index b23f8b7..0000000 --- a/src/stanza/client/iq.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::str::FromStr; - -use peanuts::{ -    element::{FromElement, IntoElement}, -    DeserializeError, Element, XML_NS, -}; - -use crate::{ -    stanza::{ -        bind::{self, Bind}, -        client::error::Error, -    }, -    JID, -}; - -use super::XMLNS; - -pub struct Iq { -    pub from: Option<JID>, -    pub id: String, -    pub to: Option<JID>, -    pub r#type: IqType, -    pub lang: Option<String>, -    // children -    // ##other -    pub query: Option<Query>, -    pub errors: Vec<Error>, -} - -#[derive(Clone)] -pub enum Query { -    Bind(Bind), -    Unsupported, -} - -impl FromElement for Query { -    fn from_element(element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        match element.identify() { -            (Some(bind::XMLNS), "bind") => Ok(Query::Bind(Bind::from_element(element)?)), -            _ => Ok(Query::Unsupported), -        } -    } -} - -impl IntoElement for Query { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        match self { -            Query::Bind(bind) => bind.builder(), -            // TODO: consider what to do if attempt to serialize unsupported -            Query::Unsupported => todo!(), -        } -    } -} - -impl FromElement for Iq { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("iq")?; -        element.check_namespace(XMLNS)?; - -        let from = element.attribute_opt("from")?; -        let id = element.attribute("id")?; -        let to = element.attribute_opt("to")?; -        let r#type = element.attribute("type")?; -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; -        let query = element.pop_child_opt()?; -        let errors = element.pop_children()?; - -        Ok(Iq { -            from, -            id, -            to, -            r#type, -            lang, -            query, -            errors, -        }) -    } -} - -impl IntoElement for Iq { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("iq", Some(XMLNS)) -            .push_attribute_opt("from", self.from.clone()) -            .push_attribute("id", self.id.clone()) -            .push_attribute_opt("to", self.to.clone()) -            .push_attribute("type", self.r#type) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_child_opt(self.query.clone()) -            .push_children(self.errors.clone()) -    } -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum IqType { -    Error, -    Get, -    Result, -    Set, -} - -impl FromStr for IqType { -    type Err = DeserializeError; - -    fn from_str(s: &str) -> Result<Self, Self::Err> { -        match s { -            "error" => Ok(IqType::Error), -            "get" => Ok(IqType::Get), -            "result" => Ok(IqType::Result), -            "set" => Ok(IqType::Set), -            _ => Err(DeserializeError::FromStr(s.to_string())), -        } -    } -} - -impl ToString for IqType { -    fn to_string(&self) -> String { -        match self { -            IqType::Error => "error".to_string(), -            IqType::Get => "get".to_string(), -            IqType::Result => "result".to_string(), -            IqType::Set => "set".to_string(), -        } -    } -} diff --git a/src/stanza/client/message.rs b/src/stanza/client/message.rs deleted file mode 100644 index 626d781..0000000 --- a/src/stanza/client/message.rs +++ /dev/null @@ -1,186 +0,0 @@ -use std::str::FromStr; - -use peanuts::{ -    element::{FromElement, IntoElement}, -    DeserializeError, Element, XML_NS, -}; - -use crate::JID; - -use super::XMLNS; - -pub struct Message { -    from: Option<JID>, -    id: Option<String>, -    to: Option<JID>, -    // can be omitted, if so default to normal -    r#type: MessageType, -    lang: Option<String>, -    // children -    subject: Option<Subject>, -    body: Option<Body>, -    thread: Option<Thread>, -} - -impl FromElement for Message { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("message")?; -        element.check_namespace(XMLNS)?; - -        let from = element.attribute_opt("from")?; -        let id = element.attribute_opt("id")?; -        let to = element.attribute_opt("to")?; -        let r#type = element.attribute_opt("type")?.unwrap_or_default(); -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - -        let subject = element.child_opt()?; -        let body = element.child_opt()?; -        let thread = element.child_opt()?; - -        Ok(Message { -            from, -            id, -            to, -            r#type, -            lang, -            subject, -            body, -            thread, -        }) -    } -} - -impl IntoElement for Message { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("message", Some(XMLNS)) -            .push_attribute_opt("from", self.from.clone()) -            .push_attribute_opt("id", self.id.clone()) -            .push_attribute_opt("to", self.to.clone()) -            .push_attribute_opt("type", { -                if self.r#type == MessageType::Normal { -                    None -                } else { -                    Some(self.r#type) -                } -            }) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_child_opt(self.subject.clone()) -            .push_child_opt(self.body.clone()) -            .push_child_opt(self.thread.clone()) -    } -} - -#[derive(Default, PartialEq, Eq, Copy, Clone)] -pub enum MessageType { -    Chat, -    Error, -    Groupchat, -    Headline, -    #[default] -    Normal, -} - -impl FromStr for MessageType { -    type Err = DeserializeError; - -    fn from_str(s: &str) -> Result<Self, Self::Err> { -        match s { -            "chat" => Ok(MessageType::Chat), -            "error" => Ok(MessageType::Error), -            "groupchat" => Ok(MessageType::Groupchat), -            "headline" => Ok(MessageType::Headline), -            "normal" => Ok(MessageType::Normal), -            _ => Err(DeserializeError::FromStr(s.to_string())), -        } -    } -} - -impl ToString for MessageType { -    fn to_string(&self) -> String { -        match self { -            MessageType::Chat => "chat".to_string(), -            MessageType::Error => "error".to_string(), -            MessageType::Groupchat => "groupchat".to_string(), -            MessageType::Headline => "headline".to_string(), -            MessageType::Normal => "normal".to_string(), -        } -    } -} - -#[derive(Clone)] -pub struct Body { -    lang: Option<String>, -    body: Option<String>, -} - -impl FromElement for Body { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("body")?; -        element.check_namespace(XMLNS)?; - -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; -        let body = element.pop_value_opt()?; - -        Ok(Body { lang, body }) -    } -} - -impl IntoElement for Body { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("body", Some(XMLNS)) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_text_opt(self.body.clone()) -    } -} - -#[derive(Clone)] -pub struct Subject { -    lang: Option<String>, -    subject: Option<String>, -} - -impl FromElement for Subject { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("subject")?; -        element.check_namespace(XMLNS)?; - -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; -        let subject = element.pop_value_opt()?; - -        Ok(Subject { lang, subject }) -    } -} - -impl IntoElement for Subject { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("subject", Some(XMLNS)) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_text_opt(self.subject.clone()) -    } -} - -#[derive(Clone)] -pub struct Thread { -    parent: Option<String>, -    thread: Option<String>, -} - -impl FromElement for Thread { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("thread")?; -        element.check_namespace(XMLNS)?; - -        let parent = element.attribute_opt("parent")?; -        let thread = element.pop_value_opt()?; - -        Ok(Thread { parent, thread }) -    } -} - -impl IntoElement for Thread { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("thread", Some(XMLNS)) -            .push_attribute_opt("parent", self.parent.clone()) -            .push_text_opt(self.thread.clone()) -    } -} diff --git a/src/stanza/client/mod.rs b/src/stanza/client/mod.rs deleted file mode 100644 index 2b063d6..0000000 --- a/src/stanza/client/mod.rs +++ /dev/null @@ -1,61 +0,0 @@ -use iq::Iq; -use message::Message; -use peanuts::{ -    element::{Content, ContentBuilder, FromContent, FromElement, IntoContent, IntoElement}, -    DeserializeError, -}; -use presence::Presence; - -use super::stream::{self, Error as StreamError}; - -pub mod error; -pub mod iq; -pub mod message; -pub mod presence; - -pub const XMLNS: &str = "jabber:client"; - -pub enum Stanza { -    Message(Message), -    Presence(Presence), -    Iq(Iq), -    Error(StreamError), -    OtherContent(Content), -} - -impl FromContent for Stanza { -    fn from_content(content: Content) -> peanuts::element::DeserializeResult<Self> { -        match content { -            Content::Element(element) => Ok(Stanza::from_element(element)?), -            Content::Text(_) => Ok(Stanza::OtherContent(content)), -            Content::PI => Ok(Stanza::OtherContent(content)), -            Content::Comment(_) => Ok(Stanza::OtherContent(content)), -        } -    } -} - -impl FromElement for Stanza { -    fn from_element(element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        match element.identify() { -            (Some(XMLNS), "message") => Ok(Stanza::Message(Message::from_element(element)?)), -            (Some(XMLNS), "presence") => Ok(Stanza::Presence(Presence::from_element(element)?)), -            (Some(XMLNS), "iq") => Ok(Stanza::Iq(Iq::from_element(element)?)), -            (Some(stream::XMLNS), "error") => { -                Ok(Stanza::Error(StreamError::from_element(element)?)) -            } -            _ => Err(DeserializeError::UnexpectedElement(element)), -        } -    } -} - -impl IntoContent for Stanza { -    fn builder(&self) -> peanuts::element::ContentBuilder { -        match self { -            Stanza::Message(message) => <Message as IntoContent>::builder(message), -            Stanza::Presence(presence) => <Presence as IntoContent>::builder(presence), -            Stanza::Iq(iq) => <Iq as IntoContent>::builder(iq), -            Stanza::Error(error) => <StreamError as IntoContent>::builder(error), -            Stanza::OtherContent(_content) => ContentBuilder::Comment("other-content".to_string()), -        } -    } -} diff --git a/src/stanza/client/presence.rs b/src/stanza/client/presence.rs deleted file mode 100644 index bcb04d4..0000000 --- a/src/stanza/client/presence.rs +++ /dev/null @@ -1,226 +0,0 @@ -use std::str::FromStr; - -use peanuts::{ -    element::{FromElement, IntoElement}, -    DeserializeError, Element, XML_NS, -}; - -use crate::JID; - -use super::{error::Error, XMLNS}; - -pub struct Presence { -    from: Option<JID>, -    id: Option<String>, -    to: Option<JID>, -    r#type: Option<PresenceType>, -    lang: Option<String>, -    // children -    show: Option<Show>, -    status: Option<Status>, -    priority: Option<Priority>, -    // TODO: ##other -    // other: Vec<Other>, -    errors: Vec<Error>, -} - -impl FromElement for Presence { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("presence")?; -        element.check_namespace(XMLNS)?; - -        let from = element.attribute_opt("from")?; -        let id = element.attribute_opt("id")?; -        let to = element.attribute_opt("to")?; -        let r#type = element.attribute_opt("type")?; -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - -        let show = element.child_opt()?; -        let status = element.child_opt()?; -        let priority = element.child_opt()?; -        let errors = element.children()?; - -        Ok(Presence { -            from, -            id, -            to, -            r#type, -            lang, -            show, -            status, -            priority, -            errors, -        }) -    } -} - -impl IntoElement for Presence { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("presence", Some(XMLNS)) -            .push_attribute_opt("from", self.from.clone()) -            .push_attribute_opt("id", self.id.clone()) -            .push_attribute_opt("to", self.to.clone()) -            .push_attribute_opt("type", self.r#type) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_child_opt(self.show) -            .push_child_opt(self.status.clone()) -            .push_child_opt(self.priority) -            .push_children(self.errors.clone()) -    } -} - -pub enum Other {} - -#[derive(Copy, Clone)] -pub enum PresenceType { -    Error, -    Probe, -    Subscribe, -    Subscribed, -    Unavailable, -    Unsubscribe, -    Unsubscribed, -} - -impl FromStr for PresenceType { -    type Err = DeserializeError; - -    fn from_str(s: &str) -> Result<Self, Self::Err> { -        match s { -            "error" => Ok(PresenceType::Error), -            "probe" => Ok(PresenceType::Probe), -            "subscribe" => Ok(PresenceType::Subscribe), -            "subscribed" => Ok(PresenceType::Subscribed), -            "unavailable" => Ok(PresenceType::Unavailable), -            "unsubscribe" => Ok(PresenceType::Unsubscribe), -            "unsubscribed" => Ok(PresenceType::Unsubscribed), -            s => Err(DeserializeError::FromStr(s.to_string())), -        } -    } -} - -impl ToString for PresenceType { -    fn to_string(&self) -> String { -        match self { -            PresenceType::Error => "error".to_string(), -            PresenceType::Probe => "probe".to_string(), -            PresenceType::Subscribe => "subscribe".to_string(), -            PresenceType::Subscribed => "subscribed".to_string(), -            PresenceType::Unavailable => "unavailable".to_string(), -            PresenceType::Unsubscribe => "unsubscribe".to_string(), -            PresenceType::Unsubscribed => "unsubscribed".to_string(), -        } -    } -} - -#[derive(Copy, Clone)] -pub enum Show { -    Away, -    Chat, -    Dnd, -    Xa, -} - -impl FromElement for Show { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("show")?; -        element.check_namespace(XMLNS)?; - -        Ok(element.pop_value()?) -    } -} - -impl FromStr for Show { -    type Err = DeserializeError; - -    fn from_str(s: &str) -> Result<Self, Self::Err> { -        match s { -            "away" => Ok(Show::Away), -            "chat" => Ok(Show::Chat), -            "dnd" => Ok(Show::Dnd), -            "xa" => Ok(Show::Xa), -            s => Err(DeserializeError::FromStr(s.to_string())), -        } -    } -} - -impl IntoElement for Show { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("show", Some(XMLNS)).push_text(*self) -    } -} - -impl ToString for Show { -    fn to_string(&self) -> String { -        match self { -            Show::Away => "away".to_string(), -            Show::Chat => "chat".to_string(), -            Show::Dnd => "dnd".to_string(), -            Show::Xa => "xa".to_string(), -        } -    } -} - -#[derive(Clone)] -pub struct Status { -    lang: Option<String>, -    status: String1024, -} - -impl FromElement for Status { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("status")?; -        element.check_namespace(XMLNS)?; - -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; -        let status = element.pop_value()?; - -        Ok(Status { lang, status }) -    } -} - -impl IntoElement for Status { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("status", Some(XMLNS)) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_text(self.status.clone()) -    } -} - -// TODO: enforce? -/// minLength 1 maxLength 1024 -#[derive(Clone)] -pub struct String1024(pub String); - -impl FromStr for String1024 { -    type Err = DeserializeError; - -    fn from_str(s: &str) -> Result<Self, Self::Err> { -        Ok(String1024(s.to_string())) -    } -} - -impl ToString for String1024 { -    fn to_string(&self) -> String { -        self.0.clone() -    } -} - -// xs:byte -#[derive(Clone, Copy)] -pub struct Priority(pub i8); - -impl FromElement for Priority { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("priority")?; -        element.check_namespace(XMLNS)?; - -        Ok(Priority(element.pop_value()?)) -    } -} - -impl IntoElement for Priority { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("priority", Some(XMLNS)).push_text(self.0) -    } -} diff --git a/src/stanza/mod.rs b/src/stanza/mod.rs deleted file mode 100644 index 32716d3..0000000 --- a/src/stanza/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -use peanuts::declaration::VersionInfo; - -pub mod bind; -pub mod client; -pub mod sasl; -pub mod stanza_error; -pub mod starttls; -pub mod stream; -pub mod stream_error; - -pub static XML_VERSION: VersionInfo = VersionInfo::One; diff --git a/src/stanza/sasl.rs b/src/stanza/sasl.rs deleted file mode 100644 index ec6f63c..0000000 --- a/src/stanza/sasl.rs +++ /dev/null @@ -1,246 +0,0 @@ -use std::ops::Deref; - -use peanuts::{ -    element::{FromElement, IntoElement}, -    DeserializeError, Element, -}; -use tracing::debug; - -pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-sasl"; - -#[derive(Debug, Clone)] -pub struct Mechanisms { -    pub mechanisms: Vec<String>, -} - -impl FromElement for Mechanisms { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("mechanisms")?; -        element.check_namespace(XMLNS)?; -        debug!("getting mechanisms"); -        let mechanisms: Vec<Mechanism> = element.pop_children()?; -        debug!("gottting mechanisms"); -        let mechanisms = mechanisms -            .into_iter() -            .map(|Mechanism(mechanism)| mechanism) -            .collect(); -        debug!("gottting mechanisms"); - -        Ok(Mechanisms { mechanisms }) -    } -} - -impl IntoElement for Mechanisms { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("mechanisms", Some(XMLNS)).push_children( -            self.mechanisms -                .iter() -                .map(|mechanism| Mechanism(mechanism.to_string())) -                .collect(), -        ) -    } -} - -pub struct Mechanism(String); - -impl FromElement for Mechanism { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("mechanism")?; -        element.check_namespace(XMLNS)?; - -        let mechanism = element.pop_value()?; - -        Ok(Mechanism(mechanism)) -    } -} - -impl IntoElement for Mechanism { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("mechanism", Some(XMLNS)).push_text(self.0.clone()) -    } -} - -impl Deref for Mechanism { -    type Target = str; - -    fn deref(&self) -> &Self::Target { -        &self.0 -    } -} - -#[derive(Debug)] -pub struct Auth { -    pub mechanism: String, -    pub sasl_data: String, -} - -impl IntoElement for Auth { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("auth", Some(XMLNS)) -            .push_attribute("mechanism", self.mechanism.clone()) -            .push_text(self.sasl_data.clone()) -    } -} - -#[derive(Debug)] -pub struct Challenge(String); - -impl Deref for Challenge { -    type Target = str; - -    fn deref(&self) -> &Self::Target { -        &self.0 -    } -} - -impl FromElement for Challenge { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("challenge")?; -        element.check_namespace(XMLNS)?; - -        let sasl_data = element.value()?; - -        Ok(Challenge(sasl_data)) -    } -} - -#[derive(Debug)] -pub struct Success(Option<String>); - -impl Deref for Success { -    type Target = Option<String>; - -    fn deref(&self) -> &Self::Target { -        &self.0 -    } -} - -impl FromElement for Success { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("success")?; -        element.check_namespace(XMLNS)?; - -        let sasl_data = element.value_opt()?; - -        Ok(Success(sasl_data)) -    } -} - -#[derive(Debug)] -pub enum ServerResponse { -    Challenge(Challenge), -    Success(Success), -    Failure(Failure), -} - -impl FromElement for ServerResponse { -    fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { -        debug!("identification: {:?}", element.identify()); -        match element.identify() { -            (Some(XMLNS), "challenge") => { -                Ok(ServerResponse::Challenge(Challenge::from_element(element)?)) -            } -            (Some(XMLNS), "success") => { -                Ok(ServerResponse::Success(Success::from_element(element)?)) -            } -            (Some(XMLNS), "failure") => { -                Ok(ServerResponse::Failure(Failure::from_element(element)?)) -            } -            _ => Err(DeserializeError::UnexpectedElement(element)), -        } -    } -} - -#[derive(Debug)] -pub struct Response(String); - -impl Response { -    pub fn new(response: String) -> Self { -        Self(response) -    } -} - -impl Deref for Response { -    type Target = str; - -    fn deref(&self) -> &Self::Target { -        &self.0 -    } -} - -impl IntoElement for Response { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("response", Some(XMLNS)).push_text(self.0.clone()) -    } -} - -#[derive(Debug)] -pub struct Failure { -    r#type: Option<FailureType>, -    text: Option<Text>, -} - -impl FromElement for Failure { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("failure")?; -        element.check_namespace(XMLNS)?; - -        let r#type = element.pop_child_opt()?; -        let text = element.pop_child_opt()?; - -        Ok(Failure { r#type, text }) -    } -} - -#[derive(Debug)] -pub enum FailureType { -    Aborted, -    AccountDisabled, -    CredentialsExpired, -    EncryptionRequired, -    IncorrectEncoding, -    InvalidAuthzid, -    InvalidMechanism, -    MalformedRequest, -    MechanismTooWeak, -    NotAuthorized, -    TemporaryAuthFailure, -} - -impl FromElement for FailureType { -    fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { -        match element.identify() { -            (Some(XMLNS), "aborted") => Ok(FailureType::Aborted), -            (Some(XMLNS), "account-disabled") => Ok(FailureType::AccountDisabled), -            (Some(XMLNS), "credentials-expired") => Ok(FailureType::CredentialsExpired), -            (Some(XMLNS), "encryption-required") => Ok(FailureType::EncryptionRequired), -            (Some(XMLNS), "incorrect-encoding") => Ok(FailureType::IncorrectEncoding), -            (Some(XMLNS), "invalid-authzid") => Ok(FailureType::InvalidAuthzid), -            (Some(XMLNS), "invalid-mechanism") => Ok(FailureType::InvalidMechanism), -            (Some(XMLNS), "malformed-request") => Ok(FailureType::MalformedRequest), -            (Some(XMLNS), "mechanism-too-weak") => Ok(FailureType::MechanismTooWeak), -            (Some(XMLNS), "not-authorized") => Ok(FailureType::NotAuthorized), -            (Some(XMLNS), "temporary-auth-failure") => Ok(FailureType::TemporaryAuthFailure), -            _ => Err(DeserializeError::UnexpectedElement(element)), -        } -    } -} - -#[derive(Debug)] -pub struct Text { -    lang: Option<String>, -    text: Option<String>, -} - -impl FromElement for Text { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("text")?; -        element.check_namespace(XMLNS)?; - -        let lang = element.attribute_opt_namespaced("lang", peanuts::XML_NS)?; - -        let text = element.pop_value_opt()?; - -        Ok(Text { lang, text }) -    } -} diff --git a/src/stanza/stanza_error.rs b/src/stanza/stanza_error.rs deleted file mode 100644 index 99c1f15..0000000 --- a/src/stanza/stanza_error.rs +++ /dev/null @@ -1,126 +0,0 @@ -// https://datatracker.ietf.org/doc/html/rfc6120#appendix-A.8 - -use peanuts::{ -    element::{FromElement, IntoElement}, -    Element, XML_NS, -}; - -pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-stanzas"; - -#[derive(Clone, Debug)] -pub enum Error { -    BadRequest, -    Conflict, -    FeatureNotImplemented, -    Forbidden, -    Gone(Option<String>), -    InternalServerError, -    ItemNotFound, -    JidMalformed, -    NotAcceptable, -    NotAllowed, -    NotAuthorized, -    PolicyViolation, -    RecipientUnavailable, -    Redirect(Option<String>), -    RegistrationRequired, -    RemoteServerNotFound, -    RemoteServerTimeout, -    ResourceConstraint, -    ServiceUnavailable, -    SubscriptionRequired, -    UndefinedCondition, -    UnexpectedRequest, -} - -impl FromElement for Error { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        let error; -        match element.identify() { -            (Some(XMLNS), "bad-request") => error = Error::BadRequest, -            (Some(XMLNS), "conflict") => error = Error::Conflict, -            (Some(XMLNS), "feature-not-implemented") => error = Error::FeatureNotImplemented, -            (Some(XMLNS), "forbidden") => error = Error::Forbidden, -            (Some(XMLNS), "gone") => return Ok(Error::Gone(element.pop_value_opt()?)), -            (Some(XMLNS), "internal-server-error") => error = Error::InternalServerError, -            (Some(XMLNS), "item-not-found") => error = Error::ItemNotFound, -            (Some(XMLNS), "jid-malformed") => error = Error::JidMalformed, -            (Some(XMLNS), "not-acceptable") => error = Error::NotAcceptable, -            (Some(XMLNS), "not-allowed") => error = Error::NotAllowed, -            (Some(XMLNS), "not-authorized") => error = Error::NotAuthorized, -            (Some(XMLNS), "policy-violation") => error = Error::PolicyViolation, -            (Some(XMLNS), "recipient-unavailable") => error = Error::RecipientUnavailable, -            (Some(XMLNS), "redirect") => return Ok(Error::Redirect(element.pop_value_opt()?)), -            (Some(XMLNS), "registration-required") => error = Error::RegistrationRequired, -            (Some(XMLNS), "remote-server-not-found") => error = Error::RemoteServerNotFound, -            (Some(XMLNS), "remote-server-timeout") => error = Error::RemoteServerTimeout, -            (Some(XMLNS), "resource-constraint") => error = Error::ResourceConstraint, -            (Some(XMLNS), "service-unavailable") => error = Error::ServiceUnavailable, -            (Some(XMLNS), "subscription-required") => error = Error::SubscriptionRequired, -            (Some(XMLNS), "undefined-condition") => error = Error::UndefinedCondition, -            (Some(XMLNS), "unexpected-request") => error = Error::UnexpectedRequest, -            _ => return Err(peanuts::DeserializeError::UnexpectedElement(element)), -        } -        element.no_more_content()?; -        return Ok(error); -    } -} - -impl IntoElement for Error { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        match self { -            Error::BadRequest => Element::builder("bad-request", Some(XMLNS)), -            Error::Conflict => Element::builder("conflict", Some(XMLNS)), -            Error::FeatureNotImplemented => { -                Element::builder("feature-not-implemented", Some(XMLNS)) -            } -            Error::Forbidden => Element::builder("forbidden", Some(XMLNS)), -            Error::Gone(r) => Element::builder("gone", Some(XMLNS)).push_text_opt(r.clone()), -            Error::InternalServerError => Element::builder("internal-server-error", Some(XMLNS)), -            Error::ItemNotFound => Element::builder("item-not-found", Some(XMLNS)), -            Error::JidMalformed => Element::builder("jid-malformed", Some(XMLNS)), -            Error::NotAcceptable => Element::builder("not-acceptable", Some(XMLNS)), -            Error::NotAllowed => Element::builder("not-allowed", Some(XMLNS)), -            Error::NotAuthorized => Element::builder("not-authorized", Some(XMLNS)), -            Error::PolicyViolation => Element::builder("policy-violation", Some(XMLNS)), -            Error::RecipientUnavailable => Element::builder("recipient-unavailable", Some(XMLNS)), -            Error::Redirect(r) => { -                Element::builder("redirect", Some(XMLNS)).push_text_opt(r.clone()) -            } -            Error::RegistrationRequired => Element::builder("registration-required", Some(XMLNS)), -            Error::RemoteServerNotFound => Element::builder("remote-server-not-found", Some(XMLNS)), -            Error::RemoteServerTimeout => Element::builder("remote-server-timeout", Some(XMLNS)), -            Error::ResourceConstraint => Element::builder("resource-constraint", Some(XMLNS)), -            Error::ServiceUnavailable => Element::builder("service-unavailable", Some(XMLNS)), -            Error::SubscriptionRequired => Element::builder("subscription-required", Some(XMLNS)), -            Error::UndefinedCondition => Element::builder("undefined-condition", Some(XMLNS)), -            Error::UnexpectedRequest => Element::builder("unexpected-request", Some(XMLNS)), -        } -    } -} - -#[derive(Clone, Debug)] -pub struct Text { -    lang: Option<String>, -    text: Option<String>, -} - -impl FromElement for Text { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("text")?; -        element.check_name(XMLNS)?; - -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; -        let text = element.pop_value_opt()?; - -        Ok(Text { lang, text }) -    } -} - -impl IntoElement for Text { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("text", Some(XMLNS)) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_text_opt(self.text.clone()) -    } -} diff --git a/src/stanza/starttls.rs b/src/stanza/starttls.rs deleted file mode 100644 index fb66711..0000000 --- a/src/stanza/starttls.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::collections::{HashMap, HashSet}; - -use peanuts::{ -    element::{Content, FromElement, IntoElement, Name, NamespaceDeclaration}, -    Element, -}; - -pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-tls"; - -#[derive(Debug, Clone)] -pub struct StartTls { -    pub required: bool, -} - -impl IntoElement for StartTls { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        let mut builder = Element::builder("starttls", Some(XMLNS)); - -        if self.required { -            builder = builder.push_child(Required) -        } - -        builder -    } -} - -impl FromElement for StartTls { -    fn from_element( -        mut element: peanuts::Element, -    ) -> std::result::Result<StartTls, peanuts::DeserializeError> { -        element.check_name("starttls")?; -        element.check_namespace(XMLNS)?; - -        let mut required = false; -        if let Some(_) = element.child_opt::<Required>()? { -            required = true; -        } - -        Ok(StartTls { required }) -    } -} - -#[derive(Debug)] -pub struct Required; - -impl FromElement for Required { -    fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("required")?; -        element.check_namespace(XMLNS)?; - -        Ok(Required) -    } -} - -impl IntoElement for Required { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("required", Some(XMLNS)) -    } -} - -#[derive(Debug)] -pub struct Proceed; - -impl IntoElement for Proceed { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("proceed", Some(XMLNS)) -    } -} - -impl FromElement for Proceed { -    fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("proceed")?; -        element.check_namespace(XMLNS)?; - -        Ok(Proceed) -    } -} - -pub struct Failure; - -impl IntoElement for Failure { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("failure", Some(XMLNS)) -    } -} - -impl FromElement for Failure { -    fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("failure")?; -        element.check_namespace(XMLNS)?; - -        Ok(Failure) -    } -} diff --git a/src/stanza/stream.rs b/src/stanza/stream.rs deleted file mode 100644 index 84d62d9..0000000 --- a/src/stanza/stream.rs +++ /dev/null @@ -1,191 +0,0 @@ -use std::collections::{HashMap, HashSet}; - -use peanuts::element::{Content, ElementBuilder, FromElement, IntoElement, NamespaceDeclaration}; -use peanuts::XML_NS; -use peanuts::{element::Name, Element}; -use tracing::debug; - -use crate::stanza::bind; -use crate::JID; - -use super::sasl::{self, Mechanisms}; -use super::starttls::{self, StartTls}; -use super::stream_error::{Error as StreamError, Text}; -use super::{client, stream_error}; - -pub const XMLNS: &str = "http://etherx.jabber.org/streams"; - -// MUST be qualified by stream namespace -// #[derive(XmlSerialize, XmlDeserialize)] -// #[peanuts(xmlns = XMLNS)] -#[derive(Debug)] -pub struct Stream { -    pub from: Option<JID>, -    to: Option<JID>, -    id: Option<String>, -    version: Option<String>, -    // TODO: lang enum -    lang: Option<String>, -    // #[peanuts(content)] -    // content: Message, -} - -impl FromElement for Stream { -    fn from_element(mut element: Element) -> std::result::Result<Self, peanuts::DeserializeError> { -        element.check_namespace(XMLNS)?; -        element.check_name("stream")?; - -        let from = element.attribute_opt("from")?; -        let to = element.attribute_opt("to")?; -        let id = element.attribute_opt("id")?; -        let version = element.attribute_opt("version")?; -        let lang = element.attribute_opt_namespaced("lang", peanuts::XML_NS)?; - -        Ok(Stream { -            from, -            to, -            id, -            version, -            lang, -        }) -    } -} - -impl IntoElement for Stream { -    fn builder(&self) -> ElementBuilder { -        Element::builder("stream", Some(XMLNS.to_string())) -            .push_namespace_declaration_override(Some("stream"), XMLNS) -            .push_namespace_declaration_override(None::<&str>, client::XMLNS) -            .push_attribute_opt("to", self.to.clone()) -            .push_attribute_opt("from", self.from.clone()) -            .push_attribute_opt("id", self.id.clone()) -            .push_attribute_opt("version", self.version.clone()) -            .push_attribute_opt_namespaced(peanuts::XML_NS, "to", self.lang.clone()) -    } -} - -impl<'s> Stream { -    pub fn new( -        from: Option<JID>, -        to: Option<JID>, -        id: Option<String>, -        version: Option<String>, -        lang: Option<String>, -    ) -> Self { -        Self { -            from, -            to, -            id, -            version, -            lang, -        } -    } - -    /// For initial stream headers, the initiating entity SHOULD include the 'xml:lang' attribute. -    /// For privacy, it is better to not set `from` when sending a client stanza over an unencrypted connection. -    pub fn new_client(from: Option<JID>, to: JID, id: Option<String>, lang: String) -> Self { -        Self { -            from, -            to: Some(to), -            id, -            version: Some("1.0".to_string()), -            lang: Some(lang), -        } -    } -} - -#[derive(Debug)] -pub struct Features { -    pub features: Vec<Feature>, -} - -impl IntoElement for Features { -    fn builder(&self) -> ElementBuilder { -        Element::builder("features", Some(XMLNS)).push_children(self.features.clone()) -    } -} - -impl FromElement for Features { -    fn from_element( -        mut element: Element, -    ) -> std::result::Result<Features, peanuts::DeserializeError> { -        element.check_namespace(XMLNS)?; -        element.check_name("features")?; - -        debug!("got features stanza"); -        let features = element.children()?; -        debug!("got features period"); - -        Ok(Features { features }) -    } -} - -#[derive(Debug, Clone)] -pub enum Feature { -    StartTls(StartTls), -    Sasl(Mechanisms), -    Bind, -    Unknown, -} - -impl IntoElement for Feature { -    fn builder(&self) -> ElementBuilder { -        match self { -            Feature::StartTls(start_tls) => start_tls.builder(), -            Feature::Sasl(mechanisms) => mechanisms.builder(), -            Feature::Bind => todo!(), -            Feature::Unknown => todo!(), -        } -    } -} - -impl FromElement for Feature { -    fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { -        let identity = element.identify(); -        debug!("identity: {:?}", identity); -        match element.identify() { -            (Some(starttls::XMLNS), "starttls") => { -                debug!("identified starttls"); -                Ok(Feature::StartTls(StartTls::from_element(element)?)) -            } -            (Some(sasl::XMLNS), "mechanisms") => { -                debug!("identified mechanisms"); -                Ok(Feature::Sasl(Mechanisms::from_element(element)?)) -            } -            (Some(bind::XMLNS), "bind") => { -                debug!("identified bind"); -                Ok(Feature::Bind) -            } -            _ => { -                debug!("identified unknown feature"); -                Ok(Feature::Unknown) -            } -        } -    } -} - -#[derive(Debug)] -pub struct Error { -    error: StreamError, -    text: Option<Text>, -} - -impl FromElement for Error { -    fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("error")?; -        element.check_namespace(XMLNS)?; - -        let error = element.pop_child_one()?; -        let text = element.pop_child_opt()?; - -        Ok(Error { error, text }) -    } -} - -impl IntoElement for Error { -    fn builder(&self) -> ElementBuilder { -        Element::builder("error", Some(XMLNS)) -            .push_child(self.error.clone()) -            .push_child_opt(self.text.clone()) -    } -} diff --git a/src/stanza/stream_error.rs b/src/stanza/stream_error.rs deleted file mode 100644 index 5ae04a6..0000000 --- a/src/stanza/stream_error.rs +++ /dev/null @@ -1,137 +0,0 @@ -use peanuts::{ -    element::{FromElement, IntoElement}, -    DeserializeError, Element, XML_NS, -}; - -pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-streams"; - -#[derive(Clone, Debug)] -pub enum Error { -    BadFormat, -    BadNamespacePrefix, -    Conflict, -    ConnectionTimeout, -    HostGone, -    HostUnknown, -    ImproperAddressing, -    InternalServerError, -    InvalidFrom, -    InvalidId, -    InvalidNamespace, -    InvalidXml, -    NotAuthorized, -    NotWellFormed, -    PolicyViolation, -    RemoteConnectionFailed, -    Reset, -    ResourceConstraint, -    RestrictedXml, -    SeeOtherHost(Option<String>), -    SystemShutdown, -    UndefinedCondition, -    UnsupportedEncoding, -    UnsupportedStanzaType, -    UnsupportedVersion, -} - -impl FromElement for Error { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        let error; -        match element.identify() { -            (Some(XMLNS), "bad-format") => error = Error::BadFormat, -            (Some(XMLNS), "bad-namespace-prefix") => error = Error::BadNamespacePrefix, -            (Some(XMLNS), "conflict") => error = Error::Conflict, -            (Some(XMLNS), "connection-timeout") => error = Error::ConnectionTimeout, -            (Some(XMLNS), "host-gone") => error = Error::HostGone, -            (Some(XMLNS), "host-unknown") => error = Error::HostUnknown, -            (Some(XMLNS), "improper-addressing") => error = Error::ImproperAddressing, -            (Some(XMLNS), "internal-server-error") => error = Error::InternalServerError, -            (Some(XMLNS), "invalid-from") => error = Error::InvalidFrom, -            (Some(XMLNS), "invalid-id") => error = Error::InvalidId, -            (Some(XMLNS), "invalid-namespace") => error = Error::InvalidNamespace, -            (Some(XMLNS), "invalid-xml") => error = Error::InvalidXml, -            (Some(XMLNS), "not-authorized") => error = Error::NotAuthorized, -            (Some(XMLNS), "not-well-formed") => error = Error::NotWellFormed, -            (Some(XMLNS), "policy-violation") => error = Error::PolicyViolation, -            (Some(XMLNS), "remote-connection-failed") => error = Error::RemoteConnectionFailed, -            (Some(XMLNS), "reset") => error = Error::Reset, -            (Some(XMLNS), "resource-constraint") => error = Error::ResourceConstraint, -            (Some(XMLNS), "restricted-xml") => error = Error::RestrictedXml, -            (Some(XMLNS), "see-other-host") => { -                return Ok(Error::SeeOtherHost(element.pop_value_opt()?)) -            } -            (Some(XMLNS), "system-shutdown") => error = Error::SystemShutdown, -            (Some(XMLNS), "undefined-condition") => error = Error::UndefinedCondition, -            (Some(XMLNS), "unsupported-encoding") => error = Error::UnsupportedEncoding, -            (Some(XMLNS), "unsupported-stanza-type") => error = Error::UnsupportedStanzaType, -            (Some(XMLNS), "unsupported-version") => error = Error::UnsupportedVersion, -            _ => return Err(DeserializeError::UnexpectedElement(element)), -        } -        element.no_more_content()?; -        return Ok(error); -    } -} - -impl IntoElement for Error { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        match self { -            Error::BadFormat => Element::builder("bad-format", Some(XMLNS)), -            Error::BadNamespacePrefix => Element::builder("bad-namespace-prefix", Some(XMLNS)), -            Error::Conflict => Element::builder("conflict", Some(XMLNS)), -            Error::ConnectionTimeout => Element::builder("connection-timeout", Some(XMLNS)), -            Error::HostGone => Element::builder("host-gone", Some(XMLNS)), -            Error::HostUnknown => Element::builder("host-unknown", Some(XMLNS)), -            Error::ImproperAddressing => Element::builder("improper-addressing", Some(XMLNS)), -            Error::InternalServerError => Element::builder("internal-server-error", Some(XMLNS)), -            Error::InvalidFrom => Element::builder("invalid-from", Some(XMLNS)), -            Error::InvalidId => Element::builder("invalid-id", Some(XMLNS)), -            Error::InvalidNamespace => Element::builder("invalid-namespace", Some(XMLNS)), -            Error::InvalidXml => Element::builder("invalid-xml", Some(XMLNS)), -            Error::NotAuthorized => Element::builder("not-authorized", Some(XMLNS)), -            Error::NotWellFormed => Element::builder("not-well-formed", Some(XMLNS)), -            Error::PolicyViolation => Element::builder("policy-violation", Some(XMLNS)), -            Error::RemoteConnectionFailed => { -                Element::builder("remote-connection-failed", Some(XMLNS)) -            } -            Error::Reset => Element::builder("reset", Some(XMLNS)), -            Error::ResourceConstraint => Element::builder("resource-constraint", Some(XMLNS)), -            Error::RestrictedXml => Element::builder("restricted-xml", Some(XMLNS)), -            Error::SeeOtherHost(h) => { -                Element::builder("see-other-host", Some(XMLNS)).push_text_opt(h.clone()) -            } -            Error::SystemShutdown => Element::builder("system-shutdown", Some(XMLNS)), -            Error::UndefinedCondition => Element::builder("undefined-condition", Some(XMLNS)), -            Error::UnsupportedEncoding => Element::builder("unsupported-encoding", Some(XMLNS)), -            Error::UnsupportedStanzaType => { -                Element::builder("unsupported-stanza-type", Some(XMLNS)) -            } -            Error::UnsupportedVersion => Element::builder("unsupported-version", Some(XMLNS)), -        } -    } -} - -#[derive(Clone, Debug)] -pub struct Text { -    text: Option<String>, -    lang: Option<String>, -} - -impl FromElement for Text { -    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { -        element.check_name("text")?; -        element.check_name(XMLNS)?; - -        let lang = element.attribute_opt_namespaced("lang", XML_NS)?; -        let text = element.pop_value_opt()?; - -        Ok(Text { lang, text }) -    } -} - -impl IntoElement for Text { -    fn builder(&self) -> peanuts::element::ElementBuilder { -        Element::builder("text", Some(XMLNS)) -            .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) -            .push_text_opt(self.text.clone()) -    } -} | 
