use peanuts::{ element::{FromElement, IntoElement}, DeserializeError, Element, }; pub const XMLNS: &str = "http://jabber.org/protocol/disco#info"; #[derive(Debug, Clone)] pub struct Query { pub node: Option, pub features: Vec, pub identities: Vec, } impl FromElement for Query { fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult { element.check_name("query")?; element.check_namespace(XMLNS)?; let node = element.attribute_opt("node")?; let features = element.children()?; let identities = element.children()?; Ok(Self { node, features, identities, }) } } impl IntoElement for Query { fn builder(&self) -> peanuts::element::ElementBuilder { Element::builder("query", Some(XMLNS)) .push_attribute_opt("node", self.node.clone()) .push_children(self.features.clone()) .push_children(self.identities.clone()) } } // no children #[derive(Debug, Clone)] pub struct Identity { /// non empty string pub category: String, pub name: Option, /// non empty string pub r#type: String, } impl FromElement for Identity { fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult { element.check_name("identity")?; element.check_namespace(XMLNS)?; let category: String = element.attribute("category")?; if category.is_empty() { return Err(DeserializeError::AttributeEmptyString( "category".to_string(), )); } let name = element.attribute_opt("name")?; let r#type: String = element.attribute("type")?; if r#type.is_empty() { return Err(DeserializeError::AttributeEmptyString("type".to_string())); } Ok(Self { category, name, r#type, }) } } impl IntoElement for Identity { fn builder(&self) -> peanuts::element::ElementBuilder { Element::builder("identity", Some(XMLNS)) .push_attribute("category", self.category.clone()) .push_attribute_opt("name", self.name.clone()) .push_attribute("type", self.r#type.clone()) } } // no children #[derive(Debug, Clone)] pub struct Feature { pub var: String, } impl FromElement for Feature { fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult { element.check_name("feature")?; element.check_namespace(XMLNS)?; let var = element.attribute("var")?; Ok(Self { var }) } } impl IntoElement for Feature { fn builder(&self) -> peanuts::element::ElementBuilder { Element::builder("feature", Some(XMLNS)).push_attribute("var", self.var.clone()) } }