use std::str::FromStr; use peanuts::element::{FromElement, IntoElement}; use peanuts::{DeserializeError, Element}; use crate::stanza_error::Error as StanzaError; use crate::stanza_error::Text; use super::XMLNS; #[derive(Clone, Debug)] pub struct Error { by: Option, r#type: ErrorType, // children (sequence) error: StanzaError, text: Option, } impl FromElement for Error { fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult { 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 { 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(), } } }