diff options
Diffstat (limited to 'src/stanza/error.rs')
| -rw-r--r-- | src/stanza/error.rs | 126 | 
1 files changed, 126 insertions, 0 deletions
| diff --git a/src/stanza/error.rs b/src/stanza/error.rs new file mode 100644 index 0000000..99c1f15 --- /dev/null +++ b/src/stanza/error.rs @@ -0,0 +1,126 @@ +// 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()) +    } +} | 
