aboutsummaryrefslogblamecommitdiffstats
path: root/stanza/src/xep_0059.rs
blob: 01dbc6c21d7495a7fcb78ad200340b68c628606f (plain) (tree)























































































































































































































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

pub const XMLNS: &str = "http://jabber.org/protocol/rsm";

#[derive(Debug, Clone)]
pub struct Set {
    after: Option<After>,
    before: Option<Before>,
    count: Option<Count>,
    first: Option<First>,
    index: Option<Index>,
    last: Option<Last>,
    max: Option<Max>,
}

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

        let after = element.pop_child_opt()?;
        let before = element.pop_child_opt()?;
        let count = element.pop_child_opt()?;
        let first = element.pop_child_opt()?;
        let index = element.pop_child_opt()?;
        let last = element.pop_child_opt()?;
        let max = element.pop_child_opt()?;

        Ok(Self {
            after,
            before,
            count,
            first,
            index,
            last,
            max,
        })
    }
}

impl IntoElement for Set {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        Element::builder("set", Some(XMLNS))
            .push_child_opt(self.after.clone())
            .push_child_opt(self.before.clone())
            .push_child_opt(self.count.clone())
            .push_child_opt(self.first.clone())
            .push_child_opt(self.index.clone())
            .push_child_opt(self.last.clone())
            .push_child_opt(self.max.clone())
    }
}

#[derive(Debug, Clone)]
pub struct After(pub String);

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

        Ok(Self(element.pop_value_opt()?.unwrap_or_default()))
    }
}

impl IntoElement for After {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        // TODO: better way for push_text to work, empty string should be empty element no matter what
        let builder = Element::builder("after", Some(XMLNS));

        if self.0.is_empty() {
            builder
        } else {
            builder.push_text(self.0.clone())
        }
    }
}

#[derive(Debug, Clone)]
pub struct Before(pub String);

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

        Ok(Self(element.pop_value_opt()?.unwrap_or_default()))
    }
}

impl IntoElement for Before {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        // TODO: better way for push_text to work, empty string should be empty element no matter what
        let builder = Element::builder("before", Some(XMLNS));

        if self.0.is_empty() {
            builder
        } else {
            builder.push_text(self.0.clone())
        }
    }
}

#[derive(Debug, Clone)]
pub struct Count(pub i32);

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

        Ok(Self(element.pop_value_opt()?.unwrap_or_default()))
    }
}

impl IntoElement for Count {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        Element::builder("count", Some(XMLNS)).push_text(self.0)
    }
}

#[derive(Debug, Clone)]
pub struct Index(pub i32);

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

        Ok(Self(element.pop_value_opt()?.unwrap_or_default()))
    }
}

impl IntoElement for Index {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        Element::builder("index", Some(XMLNS)).push_text(self.0)
    }
}

#[derive(Debug, Clone)]
pub struct Last(pub String);

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

        Ok(Self(element.pop_value_opt()?.unwrap_or_default()))
    }
}

impl IntoElement for Last {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        // TODO: better way for push_text to work, empty string should be empty element no matter what
        let builder = Element::builder("last", Some(XMLNS));

        if self.0.is_empty() {
            builder
        } else {
            builder.push_text(self.0.clone())
        }
    }
}

#[derive(Debug, Clone)]
pub struct Max(pub i32);

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

        Ok(Self(element.pop_value_opt()?.unwrap_or_default()))
    }
}

impl IntoElement for Max {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        Element::builder("max", Some(XMLNS)).push_text(self.0)
    }
}

#[derive(Debug, Clone)]
pub struct First {
    index: Option<i32>,
    first: String,
}

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

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

        let first = element.value_opt()?.unwrap_or_default();

        Ok(Self { index, first })
    }
}

impl IntoElement for First {
    fn builder(&self) -> peanuts::element::ElementBuilder {
        let builder =
            Element::builder("first", Some(XMLNS)).push_attribute_opt("index", self.index);

        if self.first.is_empty() {
            builder
        } else {
            builder.push_text(self.first.clone())
        }
    }
}