diff options
Diffstat (limited to 'src/stanza/client')
-rw-r--r-- | src/stanza/client/error.rs | 83 | ||||
-rw-r--r-- | src/stanza/client/iq.rs | 124 | ||||
-rw-r--r-- | src/stanza/client/message.rs | 186 | ||||
-rw-r--r-- | src/stanza/client/mod.rs | 61 | ||||
-rw-r--r-- | src/stanza/client/presence.rs | 226 |
5 files changed, 0 insertions, 680 deletions
diff --git a/src/stanza/client/error.rs b/src/stanza/client/error.rs deleted file mode 100644 index 545b9a7..0000000 --- a/src/stanza/client/error.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::str::FromStr; - -use peanuts::element::{FromElement, IntoElement}; -use peanuts::{DeserializeError, Element}; - -use crate::stanza::stanza_error::Error as StanzaError; -use crate::stanza::stanza_error::Text; - -use super::XMLNS; - -#[derive(Clone, Debug)] -pub struct Error { - by: Option<String>, - r#type: ErrorType, - // children (sequence) - error: StanzaError, - text: Option<Text>, -} - -impl FromElement for Error { - fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("error")?; - element.check_name(XMLNS)?; - - let by = element.attribute_opt("by")?; - let r#type = element.attribute("type")?; - let error = element.pop_child_one()?; - let text = element.pop_child_opt()?; - - Ok(Error { - by, - r#type, - error, - text, - }) - } -} - -impl IntoElement for Error { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("error", Some(XMLNS)) - .push_attribute_opt("by", self.by.clone()) - .push_attribute("type", self.r#type) - .push_child(self.error.clone()) - .push_child_opt(self.text.clone()) - } -} - -#[derive(Copy, Clone, Debug)] -pub enum ErrorType { - Auth, - Cancel, - Continue, - Modify, - Wait, -} - -impl FromStr for ErrorType { - type Err = DeserializeError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "auth" => Ok(ErrorType::Auth), - "cancel" => Ok(ErrorType::Cancel), - "continue" => Ok(ErrorType::Continue), - "modify" => Ok(ErrorType::Modify), - "wait" => Ok(ErrorType::Wait), - _ => Err(DeserializeError::FromStr(s.to_string())), - } - } -} - -impl ToString for ErrorType { - fn to_string(&self) -> String { - match self { - ErrorType::Auth => "auth".to_string(), - ErrorType::Cancel => "cancel".to_string(), - ErrorType::Continue => "continue".to_string(), - ErrorType::Modify => "modify".to_string(), - ErrorType::Wait => "wait".to_string(), - } - } -} diff --git a/src/stanza/client/iq.rs b/src/stanza/client/iq.rs deleted file mode 100644 index b23f8b7..0000000 --- a/src/stanza/client/iq.rs +++ /dev/null @@ -1,124 +0,0 @@ -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(), - } - } -} diff --git a/src/stanza/client/message.rs b/src/stanza/client/message.rs deleted file mode 100644 index 626d781..0000000 --- a/src/stanza/client/message.rs +++ /dev/null @@ -1,186 +0,0 @@ -use std::str::FromStr; - -use peanuts::{ - element::{FromElement, IntoElement}, - DeserializeError, Element, XML_NS, -}; - -use crate::JID; - -use super::XMLNS; - -pub struct Message { - from: Option<JID>, - id: Option<String>, - to: Option<JID>, - // can be omitted, if so default to normal - r#type: MessageType, - lang: Option<String>, - // children - subject: Option<Subject>, - body: Option<Body>, - thread: Option<Thread>, -} - -impl FromElement for Message { - fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("message")?; - element.check_namespace(XMLNS)?; - - let from = element.attribute_opt("from")?; - let id = element.attribute_opt("id")?; - let to = element.attribute_opt("to")?; - let r#type = element.attribute_opt("type")?.unwrap_or_default(); - let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - - let subject = element.child_opt()?; - let body = element.child_opt()?; - let thread = element.child_opt()?; - - Ok(Message { - from, - id, - to, - r#type, - lang, - subject, - body, - thread, - }) - } -} - -impl IntoElement for Message { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("message", Some(XMLNS)) - .push_attribute_opt("from", self.from.clone()) - .push_attribute_opt("id", self.id.clone()) - .push_attribute_opt("to", self.to.clone()) - .push_attribute_opt("type", { - if self.r#type == MessageType::Normal { - None - } else { - Some(self.r#type) - } - }) - .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) - .push_child_opt(self.subject.clone()) - .push_child_opt(self.body.clone()) - .push_child_opt(self.thread.clone()) - } -} - -#[derive(Default, PartialEq, Eq, Copy, Clone)] -pub enum MessageType { - Chat, - Error, - Groupchat, - Headline, - #[default] - Normal, -} - -impl FromStr for MessageType { - type Err = DeserializeError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "chat" => Ok(MessageType::Chat), - "error" => Ok(MessageType::Error), - "groupchat" => Ok(MessageType::Groupchat), - "headline" => Ok(MessageType::Headline), - "normal" => Ok(MessageType::Normal), - _ => Err(DeserializeError::FromStr(s.to_string())), - } - } -} - -impl ToString for MessageType { - fn to_string(&self) -> String { - match self { - MessageType::Chat => "chat".to_string(), - MessageType::Error => "error".to_string(), - MessageType::Groupchat => "groupchat".to_string(), - MessageType::Headline => "headline".to_string(), - MessageType::Normal => "normal".to_string(), - } - } -} - -#[derive(Clone)] -pub struct Body { - lang: Option<String>, - body: Option<String>, -} - -impl FromElement for Body { - fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("body")?; - element.check_namespace(XMLNS)?; - - let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - let body = element.pop_value_opt()?; - - Ok(Body { lang, body }) - } -} - -impl IntoElement for Body { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("body", Some(XMLNS)) - .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) - .push_text_opt(self.body.clone()) - } -} - -#[derive(Clone)] -pub struct Subject { - lang: Option<String>, - subject: Option<String>, -} - -impl FromElement for Subject { - fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("subject")?; - element.check_namespace(XMLNS)?; - - let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - let subject = element.pop_value_opt()?; - - Ok(Subject { lang, subject }) - } -} - -impl IntoElement for Subject { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("subject", Some(XMLNS)) - .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) - .push_text_opt(self.subject.clone()) - } -} - -#[derive(Clone)] -pub struct Thread { - parent: Option<String>, - thread: Option<String>, -} - -impl FromElement for Thread { - fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("thread")?; - element.check_namespace(XMLNS)?; - - let parent = element.attribute_opt("parent")?; - let thread = element.pop_value_opt()?; - - Ok(Thread { parent, thread }) - } -} - -impl IntoElement for Thread { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("thread", Some(XMLNS)) - .push_attribute_opt("parent", self.parent.clone()) - .push_text_opt(self.thread.clone()) - } -} diff --git a/src/stanza/client/mod.rs b/src/stanza/client/mod.rs deleted file mode 100644 index 2b063d6..0000000 --- a/src/stanza/client/mod.rs +++ /dev/null @@ -1,61 +0,0 @@ -use iq::Iq; -use message::Message; -use peanuts::{ - element::{Content, ContentBuilder, FromContent, FromElement, IntoContent, IntoElement}, - DeserializeError, -}; -use presence::Presence; - -use super::stream::{self, Error as StreamError}; - -pub mod error; -pub mod iq; -pub mod message; -pub mod presence; - -pub const XMLNS: &str = "jabber:client"; - -pub enum Stanza { - Message(Message), - Presence(Presence), - Iq(Iq), - Error(StreamError), - OtherContent(Content), -} - -impl FromContent for Stanza { - fn from_content(content: Content) -> peanuts::element::DeserializeResult<Self> { - match content { - Content::Element(element) => Ok(Stanza::from_element(element)?), - Content::Text(_) => Ok(Stanza::OtherContent(content)), - Content::PI => Ok(Stanza::OtherContent(content)), - Content::Comment(_) => Ok(Stanza::OtherContent(content)), - } - } -} - -impl FromElement for Stanza { - fn from_element(element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { - match element.identify() { - (Some(XMLNS), "message") => Ok(Stanza::Message(Message::from_element(element)?)), - (Some(XMLNS), "presence") => Ok(Stanza::Presence(Presence::from_element(element)?)), - (Some(XMLNS), "iq") => Ok(Stanza::Iq(Iq::from_element(element)?)), - (Some(stream::XMLNS), "error") => { - Ok(Stanza::Error(StreamError::from_element(element)?)) - } - _ => Err(DeserializeError::UnexpectedElement(element)), - } - } -} - -impl IntoContent for Stanza { - fn builder(&self) -> peanuts::element::ContentBuilder { - match self { - Stanza::Message(message) => <Message as IntoContent>::builder(message), - Stanza::Presence(presence) => <Presence as IntoContent>::builder(presence), - Stanza::Iq(iq) => <Iq as IntoContent>::builder(iq), - Stanza::Error(error) => <StreamError as IntoContent>::builder(error), - Stanza::OtherContent(_content) => ContentBuilder::Comment("other-content".to_string()), - } - } -} diff --git a/src/stanza/client/presence.rs b/src/stanza/client/presence.rs deleted file mode 100644 index bcb04d4..0000000 --- a/src/stanza/client/presence.rs +++ /dev/null @@ -1,226 +0,0 @@ -use std::str::FromStr; - -use peanuts::{ - element::{FromElement, IntoElement}, - DeserializeError, Element, XML_NS, -}; - -use crate::JID; - -use super::{error::Error, XMLNS}; - -pub struct Presence { - from: Option<JID>, - id: Option<String>, - to: Option<JID>, - r#type: Option<PresenceType>, - lang: Option<String>, - // children - show: Option<Show>, - status: Option<Status>, - priority: Option<Priority>, - // TODO: ##other - // other: Vec<Other>, - errors: Vec<Error>, -} - -impl FromElement for Presence { - fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("presence")?; - element.check_namespace(XMLNS)?; - - let from = element.attribute_opt("from")?; - let id = element.attribute_opt("id")?; - let to = element.attribute_opt("to")?; - let r#type = element.attribute_opt("type")?; - let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - - let show = element.child_opt()?; - let status = element.child_opt()?; - let priority = element.child_opt()?; - let errors = element.children()?; - - Ok(Presence { - from, - id, - to, - r#type, - lang, - show, - status, - priority, - errors, - }) - } -} - -impl IntoElement for Presence { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("presence", Some(XMLNS)) - .push_attribute_opt("from", self.from.clone()) - .push_attribute_opt("id", self.id.clone()) - .push_attribute_opt("to", self.to.clone()) - .push_attribute_opt("type", self.r#type) - .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) - .push_child_opt(self.show) - .push_child_opt(self.status.clone()) - .push_child_opt(self.priority) - .push_children(self.errors.clone()) - } -} - -pub enum Other {} - -#[derive(Copy, Clone)] -pub enum PresenceType { - Error, - Probe, - Subscribe, - Subscribed, - Unavailable, - Unsubscribe, - Unsubscribed, -} - -impl FromStr for PresenceType { - type Err = DeserializeError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "error" => Ok(PresenceType::Error), - "probe" => Ok(PresenceType::Probe), - "subscribe" => Ok(PresenceType::Subscribe), - "subscribed" => Ok(PresenceType::Subscribed), - "unavailable" => Ok(PresenceType::Unavailable), - "unsubscribe" => Ok(PresenceType::Unsubscribe), - "unsubscribed" => Ok(PresenceType::Unsubscribed), - s => Err(DeserializeError::FromStr(s.to_string())), - } - } -} - -impl ToString for PresenceType { - fn to_string(&self) -> String { - match self { - PresenceType::Error => "error".to_string(), - PresenceType::Probe => "probe".to_string(), - PresenceType::Subscribe => "subscribe".to_string(), - PresenceType::Subscribed => "subscribed".to_string(), - PresenceType::Unavailable => "unavailable".to_string(), - PresenceType::Unsubscribe => "unsubscribe".to_string(), - PresenceType::Unsubscribed => "unsubscribed".to_string(), - } - } -} - -#[derive(Copy, Clone)] -pub enum Show { - Away, - Chat, - Dnd, - Xa, -} - -impl FromElement for Show { - fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("show")?; - element.check_namespace(XMLNS)?; - - Ok(element.pop_value()?) - } -} - -impl FromStr for Show { - type Err = DeserializeError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "away" => Ok(Show::Away), - "chat" => Ok(Show::Chat), - "dnd" => Ok(Show::Dnd), - "xa" => Ok(Show::Xa), - s => Err(DeserializeError::FromStr(s.to_string())), - } - } -} - -impl IntoElement for Show { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("show", Some(XMLNS)).push_text(*self) - } -} - -impl ToString for Show { - fn to_string(&self) -> String { - match self { - Show::Away => "away".to_string(), - Show::Chat => "chat".to_string(), - Show::Dnd => "dnd".to_string(), - Show::Xa => "xa".to_string(), - } - } -} - -#[derive(Clone)] -pub struct Status { - lang: Option<String>, - status: String1024, -} - -impl FromElement for Status { - fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("status")?; - element.check_namespace(XMLNS)?; - - let lang = element.attribute_opt_namespaced("lang", XML_NS)?; - let status = element.pop_value()?; - - Ok(Status { lang, status }) - } -} - -impl IntoElement for Status { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("status", Some(XMLNS)) - .push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone()) - .push_text(self.status.clone()) - } -} - -// TODO: enforce? -/// minLength 1 maxLength 1024 -#[derive(Clone)] -pub struct String1024(pub String); - -impl FromStr for String1024 { - type Err = DeserializeError; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(String1024(s.to_string())) - } -} - -impl ToString for String1024 { - fn to_string(&self) -> String { - self.0.clone() - } -} - -// xs:byte -#[derive(Clone, Copy)] -pub struct Priority(pub i8); - -impl FromElement for Priority { - fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { - element.check_name("priority")?; - element.check_namespace(XMLNS)?; - - Ok(Priority(element.pop_value()?)) - } -} - -impl IntoElement for Priority { - fn builder(&self) -> peanuts::element::ElementBuilder { - Element::builder("priority", Some(XMLNS)).push_text(self.0) - } -} |