add jabber:iq:stanza parsers
This commit is contained in:
parent
27f90bd85f
commit
89351e9563
|
@ -2,6 +2,7 @@ use peanuts::declaration::VersionInfo;
|
||||||
|
|
||||||
pub mod bind;
|
pub mod bind;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
pub mod roster;
|
||||||
pub mod sasl;
|
pub mod sasl;
|
||||||
pub mod stanza_error;
|
pub mod stanza_error;
|
||||||
pub mod starttls;
|
pub mod starttls;
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use jid::JID;
|
||||||
|
use peanuts::{
|
||||||
|
element::{FromElement, IntoElement},
|
||||||
|
DeserializeError, Element,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const XMLNS: &str = "jabber:iq:roster";
|
||||||
|
|
||||||
|
pub struct Query {
|
||||||
|
ver: Option<String>,
|
||||||
|
items: Vec<Item>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromElement for Query {
|
||||||
|
fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> {
|
||||||
|
element.check_name("query")?;
|
||||||
|
element.check_namespace(XMLNS)?;
|
||||||
|
|
||||||
|
let ver = element.attribute_opt("ver")?;
|
||||||
|
let items = element.pop_children()?;
|
||||||
|
|
||||||
|
Ok(Self { ver, items })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoElement for Query {
|
||||||
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
||||||
|
Element::builder("query", Some(XMLNS))
|
||||||
|
.push_attribute_opt("ver", self.ver.clone())
|
||||||
|
.push_children(self.items.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Item {
|
||||||
|
approved: Option<bool>,
|
||||||
|
ask: bool,
|
||||||
|
jid: JID,
|
||||||
|
name: Option<String>,
|
||||||
|
subscription: Subscription,
|
||||||
|
groups: Vec<Group>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromElement for Item {
|
||||||
|
fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> {
|
||||||
|
element.check_name("item")?;
|
||||||
|
element.check_namespace(XMLNS)?;
|
||||||
|
|
||||||
|
let approved = element.attribute_opt("approved")?;
|
||||||
|
let ask = if let Some(result) = element.attribute_opt("ask")?.map(|v| {
|
||||||
|
if v == "subscribe" {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Err(DeserializeError::FromStr(v))
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
result?
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
let jid = element.attribute("jid")?;
|
||||||
|
let name = element.attribute_opt("name")?;
|
||||||
|
let subscription = element.attribute_opt("subscription")?.unwrap_or_default();
|
||||||
|
let groups = element.pop_children()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
approved,
|
||||||
|
ask,
|
||||||
|
jid,
|
||||||
|
name,
|
||||||
|
subscription,
|
||||||
|
groups,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoElement for Item {
|
||||||
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
||||||
|
Element::builder("item", Some(XMLNS))
|
||||||
|
.push_attribute_opt("approved", self.approved)
|
||||||
|
.push_attribute_opt(
|
||||||
|
"ask",
|
||||||
|
if self.ask {
|
||||||
|
Some("subscribe".to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.push_attribute("jid", self.jid.clone())
|
||||||
|
.push_attribute_opt("name", self.name.clone())
|
||||||
|
.push_attribute("subscription", self.subscription)
|
||||||
|
.push_children(self.groups.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy)]
|
||||||
|
pub enum Subscription {
|
||||||
|
Both,
|
||||||
|
From,
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Remove,
|
||||||
|
To,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Subscription {
|
||||||
|
type Err = DeserializeError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"both" => Ok(Self::Both),
|
||||||
|
"from" => Ok(Self::From),
|
||||||
|
"none" => Ok(Self::None),
|
||||||
|
"remove" => Ok(Self::Remove),
|
||||||
|
"to" => Ok(Self::To),
|
||||||
|
s => Err(DeserializeError::FromStr(s.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Subscription {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Subscription::Both => "both".to_string(),
|
||||||
|
Subscription::From => "from".to_string(),
|
||||||
|
Subscription::None => "none".to_string(),
|
||||||
|
Subscription::Remove => "remove".to_string(),
|
||||||
|
Subscription::To => "to".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Group(Option<String>);
|
||||||
|
|
||||||
|
impl FromElement for Group {
|
||||||
|
fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
|
||||||
|
element.check_name("group")?;
|
||||||
|
element.check_namespace(XMLNS)?;
|
||||||
|
|
||||||
|
let group = element.pop_value_opt()?;
|
||||||
|
|
||||||
|
Ok(Self(group))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoElement for Group {
|
||||||
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
||||||
|
Element::builder("group", Some(XMLNS)).push_text_opt(self.0.clone())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue