aboutsummaryrefslogtreecommitdiffstats
path: root/src/stanza/client/iq.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stanza/client/iq.rs')
-rw-r--r--src/stanza/client/iq.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/stanza/client/iq.rs b/src/stanza/client/iq.rs
new file mode 100644
index 0000000..b23f8b7
--- /dev/null
+++ b/src/stanza/client/iq.rs
@@ -0,0 +1,124 @@
+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(),
+ }
+ }
+}