stanza_error.rs

  1use ns;
  2use minidom::Element;
  3use util::{FromElement, FromParentElement};
  4use std::str::FromStr;
  5
  6#[derive(Copy, Clone, Debug)]
  7pub enum ErrorType {
  8    Auth,
  9    Cancel,
 10    Continue,
 11    Modify,
 12    Wait,
 13}
 14
 15impl FromStr for ErrorType {
 16    type Err = ();
 17
 18    fn from_str(s: &str) -> Result<ErrorType, ()> {
 19        Ok(match s {
 20            "auth" => ErrorType::Auth,
 21            "cancel" => ErrorType::Cancel,
 22            "continue" => ErrorType::Continue,
 23            "modify" => ErrorType::Modify,
 24            "wait" => ErrorType::Wait,
 25            _ => { return Err(()); },
 26        })
 27    }
 28}
 29
 30#[derive(Clone, Debug)]
 31pub enum Condition {
 32    BadRequest,
 33    Conflict,
 34    FeatureNotImplemented,
 35    Forbidden,
 36    Gone(Option<String>),
 37    InternalServerError,
 38    ItemNotFound,
 39    JidMalformed,
 40    NotAcceptable,
 41    NotAllowed,
 42    NotAuthorized,
 43    PolicyViolation,
 44    RecipientUnavailable,
 45    Redirect(Option<String>),
 46    RegistrationRequired,
 47    RemoteServerNotFound,
 48    RemoteServerTimeout,
 49    ResourceConstraint,
 50    ServiceUnavailable,
 51    SubscriptionRequired,
 52    UndefinedCondition,
 53    UnexpectedRequest,
 54}
 55
 56impl FromParentElement for Condition {
 57    type Err = ();
 58
 59    fn from_parent_element(elem: &Element) -> Result<Condition, ()> {
 60        if elem.has_child("bad-request", ns::STANZAS) {
 61            Ok(Condition::BadRequest)
 62        }
 63        else if elem.has_child("conflict", ns::STANZAS) {
 64            Ok(Condition::Conflict)
 65        }
 66        else if elem.has_child("feature-not-implemented", ns::STANZAS) {
 67            Ok(Condition::FeatureNotImplemented)
 68        }
 69        else if elem.has_child("forbidden", ns::STANZAS) {
 70            Ok(Condition::Forbidden)
 71        }
 72        else if let Some(alt) = elem.get_child("gone", ns::STANZAS) {
 73            let text = alt.text();
 74            let inner = if text == "" { None } else { Some(text) };
 75            Ok(Condition::Gone(inner))
 76        }
 77        else if elem.has_child("internal-server-error", ns::STANZAS) {
 78            Ok(Condition::InternalServerError)
 79        }
 80        else if elem.has_child("item-not-found", ns::STANZAS) {
 81            Ok(Condition::ItemNotFound)
 82        }
 83        else if elem.has_child("jid-malformed", ns::STANZAS) {
 84            Ok(Condition::JidMalformed)
 85        }
 86        else if elem.has_child("not-acceptable", ns::STANZAS) {
 87            Ok(Condition::NotAcceptable)
 88        }
 89        else if elem.has_child("not-allowed", ns::STANZAS) {
 90            Ok(Condition::NotAllowed)
 91        }
 92        else if elem.has_child("not-authorized", ns::STANZAS) {
 93            Ok(Condition::NotAuthorized)
 94        }
 95        else if elem.has_child("policy-violation", ns::STANZAS) {
 96            Ok(Condition::PolicyViolation)
 97        }
 98        else if elem.has_child("recipient-unavailable", ns::STANZAS) {
 99            Ok(Condition::RecipientUnavailable)
100        }
101        else if let Some(alt) = elem.get_child("redirect", ns::STANZAS) {
102            let text = alt.text();
103            let inner = if text == "" { None } else { Some(text) };
104            Ok(Condition::Redirect(inner))
105        }
106        else if elem.has_child("registration-required", ns::STANZAS) {
107            Ok(Condition::RegistrationRequired)
108        }
109        else if elem.has_child("remote-server-not-found", ns::STANZAS) {
110            Ok(Condition::RemoteServerNotFound)
111        }
112        else if elem.has_child("remote-server-timeout", ns::STANZAS) {
113            Ok(Condition::RemoteServerTimeout)
114        }
115        else if elem.has_child("resource-constraint", ns::STANZAS) {
116            Ok(Condition::ResourceConstraint)
117        }
118        else if elem.has_child("service-unavailable", ns::STANZAS) {
119            Ok(Condition::ServiceUnavailable)
120        }
121        else if elem.has_child("subscription-required", ns::STANZAS) {
122            Ok(Condition::SubscriptionRequired)
123        }
124        else if elem.has_child("undefined-condition", ns::STANZAS) {
125            Ok(Condition::UndefinedCondition)
126        }
127        else if elem.has_child("unexpected-request", ns::STANZAS) {
128            Ok(Condition::UnexpectedRequest)
129        }
130        else {
131            Err(())
132        }
133    }
134}
135
136#[derive(Clone, Debug)]
137pub struct StanzaError {
138    error_type: ErrorType,
139    text: Option<String>,
140    condition: Condition,
141}
142
143impl StanzaError {
144    pub fn new(error_type: ErrorType, text: Option<String>, condition: Condition) -> StanzaError {
145        StanzaError {
146            error_type: error_type,
147            text: text,
148            condition: condition,
149        }
150    }
151}
152
153impl FromElement for StanzaError {
154    type Err = ();
155
156    fn from_element(elem: &Element) -> Result<StanzaError, ()> {
157        if elem.is("error", ns::STANZAS) {
158            let error_type = elem.attr("type").ok_or(())?;
159            let err: ErrorType = error_type.parse().map_err(|_| ())?;
160            let condition: Condition = Condition::from_parent_element(elem)?;
161            let text = elem.get_child("text", ns::STANZAS).map(|c| c.text());
162            Ok(StanzaError {
163                error_type: err,
164                text: text,
165                condition: condition,
166            })
167        }
168        else {
169            Err(())
170        }
171    }
172}