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 client;
|
||||
pub mod roster;
|
||||
pub mod sasl;
|
||||
pub mod stanza_error;
|
||||
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