125 lines
3.1 KiB
Rust
125 lines
3.1 KiB
Rust
|
use std::str::FromStr;
|
||
|
|
||
|
use peanuts::{
|
||
|
element::{FromElement, IntoElement},
|
||
|
DeserializeError, Element, XML_NS,
|
||
|
};
|
||
|
|
||
|
use crate::{
|
||
|
stanza::{
|
||
|
bind::{self, Bind},
|
||
|
client::error::Error,
|
||
|
},
|
||
|
JID,
|
||
|
};
|
||
|
|
||
|
use super::XMLNS;
|
||
|
|
||
|
pub struct Iq {
|
||
|
pub from: Option<JID>,
|
||
|
pub id: String,
|
||
|
pub to: Option<JID>,
|
||
|
pub r#type: IqType,
|
||
|
pub lang: Option<String>,
|
||
|
// children
|
||
|
// ##other
|
||
|
pub query: Option<Query>,
|
||
|
pub errors: Vec<Error>,
|
||
|
}
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
pub enum Query {
|
||
|
Bind(Bind),
|
||
|
Unsupported,
|
||
|
}
|
||
|
|
||
|
impl FromElement for Query {
|
||
|
fn from_element(element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
|
||
|
match element.identify() {
|
||
|
(Some(bind::XMLNS), "bind") => Ok(Query::Bind(Bind::from_element(element)?)),
|
||
|
_ => Ok(Query::Unsupported),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl IntoElement for Query {
|
||
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
||
|
match self {
|
||
|
Query::Bind(bind) => bind.builder(),
|
||
|
// TODO: consider what to do if attempt to serialize unsupported
|
||
|
Query::Unsupported => todo!(),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl FromElement for Iq {
|
||
|
fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
|
||
|
element.check_name("iq")?;
|
||
|
element.check_namespace(XMLNS)?;
|
||
|
|
||
|
let from = element.attribute_opt("from")?;
|
||
|
let id = element.attribute("id")?;
|
||
|
let to = element.attribute_opt("to")?;
|
||
|
let r#type = element.attribute("type")?;
|
||
|
let lang = element.attribute_opt_namespaced("lang", XML_NS)?;
|
||
|
let query = element.pop_child_opt()?;
|
||
|
let errors = element.pop_children()?;
|
||
|
|
||
|
Ok(Iq {
|
||
|
from,
|
||
|
id,
|
||
|
to,
|
||
|
r#type,
|
||
|
lang,
|
||
|
query,
|
||
|
errors,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl IntoElement for Iq {
|
||
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
||
|
Element::builder("iq", Some(XMLNS))
|
||
|
.push_attribute_opt("from", self.from.clone())
|
||
|
.push_attribute("id", self.id.clone())
|
||
|
.push_attribute_opt("to", self.to.clone())
|
||
|
.push_attribute("type", self.r#type)
|
||
|
.push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone())
|
||
|
.push_child_opt(self.query.clone())
|
||
|
.push_children(self.errors.clone())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||
|
pub enum IqType {
|
||
|
Error,
|
||
|
Get,
|
||
|
Result,
|
||
|
Set,
|
||
|
}
|
||
|
|
||
|
impl FromStr for IqType {
|
||
|
type Err = DeserializeError;
|
||
|
|
||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||
|
match s {
|
||
|
"error" => Ok(IqType::Error),
|
||
|
"get" => Ok(IqType::Get),
|
||
|
"result" => Ok(IqType::Result),
|
||
|
"set" => Ok(IqType::Set),
|
||
|
_ => Err(DeserializeError::FromStr(s.to_string())),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ToString for IqType {
|
||
|
fn to_string(&self) -> String {
|
||
|
match self {
|
||
|
IqType::Error => "error".to_string(),
|
||
|
IqType::Get => "get".to_string(),
|
||
|
IqType::Result => "result".to_string(),
|
||
|
IqType::Set => "set".to_string(),
|
||
|
}
|
||
|
}
|
||
|
}
|