aboutsummaryrefslogblamecommitdiffstats
path: root/stanza/src/xep_0030/info.rs
blob: 94cbabbc2f30af62963e2424c7d3bdd6afda0fe6 (plain) (tree)
1
2
3
4
5
6
7
8




                                        


                            



                                                                


                                  

                                











                                                                                                 


                                       



                       

                                        





                                                           
                                                            

                                                          





                                                               







































































                                                                                                 
use peanuts::{
    element::{FromElement, IntoElement},
    DeserializeError, Element,
};

#[cfg(feature = "xep_0059")]
use crate::xep_0059::Set;

pub const XMLNS: &str = "http://jabber.org/protocol/disco#info";

#[derive(Debug, Clone)]
pub struct Query {
    pub node: Option<String>,
    pub features: Vec<Feature>,
    pub identities: Vec<Identity>,
    #[cfg(feature = "xep_0059")]
    pub set: Option<Set>,
}

impl FromElement for Query {
    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
        element.check_name("query")?;
        element.check_namespace(XMLNS)?;

        let node = element.attribute_opt("node")?;

        let features = element.children()?;
        let identities = element.children()?;

        #[cfg(feature = "xep_0059")]
        let set = element.child_opt()?;

        Ok(Self {
            node,
            features,
            identities,
            #[cfg(feature = "xep_0059")]
            set,
        })
    }
}

impl IntoElement for Query {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        let builder = Element::builder("query", Some(XMLNS))
            .push_attribute_opt("node", self.node.clone())
            .push_children(self.features.clone())
            .push_children(self.identities.clone());

        #[cfg(feature = "xep_0059")]
        let builder = builder.push_child_opt(self.set.clone());

        builder
    }
}

// no children
#[derive(Debug, Clone)]
pub struct Identity {
    /// non empty string
    pub category: String,
    pub name: Option<String>,
    /// non empty string
    pub r#type: String,
}

impl FromElement for Identity {
    fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
        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<Self> {
        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())
    }
}