2024-12-03 03:51:26 +00:00
|
|
|
use peanuts::{
|
|
|
|
element::{FromElement, IntoElement},
|
|
|
|
DeserializeError, Element, XML_NS,
|
|
|
|
};
|
|
|
|
|
|
|
|
pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-streams";
|
|
|
|
|
2024-12-04 17:38:36 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2024-12-03 03:51:26 +00:00
|
|
|
pub enum Error {
|
|
|
|
BadFormat,
|
|
|
|
BadNamespacePrefix,
|
|
|
|
Conflict,
|
|
|
|
ConnectionTimeout,
|
|
|
|
HostGone,
|
|
|
|
HostUnknown,
|
|
|
|
ImproperAddressing,
|
|
|
|
InternalServerError,
|
|
|
|
InvalidFrom,
|
|
|
|
InvalidId,
|
|
|
|
InvalidNamespace,
|
|
|
|
InvalidXml,
|
|
|
|
NotAuthorized,
|
|
|
|
NotWellFormed,
|
|
|
|
PolicyViolation,
|
|
|
|
RemoteConnectionFailed,
|
|
|
|
Reset,
|
|
|
|
ResourceConstraint,
|
|
|
|
RestrictedXml,
|
|
|
|
SeeOtherHost(Option<String>),
|
|
|
|
SystemShutdown,
|
|
|
|
UndefinedCondition,
|
|
|
|
UnsupportedEncoding,
|
|
|
|
UnsupportedStanzaType,
|
|
|
|
UnsupportedVersion,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromElement for Error {
|
|
|
|
fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
|
|
|
|
let error;
|
|
|
|
match element.identify() {
|
|
|
|
(Some(XMLNS), "bad-format") => error = Error::BadFormat,
|
|
|
|
(Some(XMLNS), "bad-namespace-prefix") => error = Error::BadNamespacePrefix,
|
|
|
|
(Some(XMLNS), "conflict") => error = Error::Conflict,
|
|
|
|
(Some(XMLNS), "connection-timeout") => error = Error::ConnectionTimeout,
|
|
|
|
(Some(XMLNS), "host-gone") => error = Error::HostGone,
|
|
|
|
(Some(XMLNS), "host-unknown") => error = Error::HostUnknown,
|
|
|
|
(Some(XMLNS), "improper-addressing") => error = Error::ImproperAddressing,
|
|
|
|
(Some(XMLNS), "internal-server-error") => error = Error::InternalServerError,
|
|
|
|
(Some(XMLNS), "invalid-from") => error = Error::InvalidFrom,
|
|
|
|
(Some(XMLNS), "invalid-id") => error = Error::InvalidId,
|
|
|
|
(Some(XMLNS), "invalid-namespace") => error = Error::InvalidNamespace,
|
|
|
|
(Some(XMLNS), "invalid-xml") => error = Error::InvalidXml,
|
|
|
|
(Some(XMLNS), "not-authorized") => error = Error::NotAuthorized,
|
|
|
|
(Some(XMLNS), "not-well-formed") => error = Error::NotWellFormed,
|
|
|
|
(Some(XMLNS), "policy-violation") => error = Error::PolicyViolation,
|
|
|
|
(Some(XMLNS), "remote-connection-failed") => error = Error::RemoteConnectionFailed,
|
|
|
|
(Some(XMLNS), "reset") => error = Error::Reset,
|
|
|
|
(Some(XMLNS), "resource-constraint") => error = Error::ResourceConstraint,
|
|
|
|
(Some(XMLNS), "restricted-xml") => error = Error::RestrictedXml,
|
|
|
|
(Some(XMLNS), "see-other-host") => {
|
|
|
|
return Ok(Error::SeeOtherHost(element.pop_value_opt()?))
|
|
|
|
}
|
|
|
|
(Some(XMLNS), "system-shutdown") => error = Error::SystemShutdown,
|
|
|
|
(Some(XMLNS), "undefined-condition") => error = Error::UndefinedCondition,
|
|
|
|
(Some(XMLNS), "unsupported-encoding") => error = Error::UnsupportedEncoding,
|
|
|
|
(Some(XMLNS), "unsupported-stanza-type") => error = Error::UnsupportedStanzaType,
|
|
|
|
(Some(XMLNS), "unsupported-version") => error = Error::UnsupportedVersion,
|
|
|
|
_ => return Err(DeserializeError::UnexpectedElement(element)),
|
|
|
|
}
|
|
|
|
element.no_more_content()?;
|
|
|
|
return Ok(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoElement for Error {
|
|
|
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
|
|
|
match self {
|
|
|
|
Error::BadFormat => Element::builder("bad-format", Some(XMLNS)),
|
|
|
|
Error::BadNamespacePrefix => Element::builder("bad-namespace-prefix", Some(XMLNS)),
|
|
|
|
Error::Conflict => Element::builder("conflict", Some(XMLNS)),
|
|
|
|
Error::ConnectionTimeout => Element::builder("connection-timeout", Some(XMLNS)),
|
|
|
|
Error::HostGone => Element::builder("host-gone", Some(XMLNS)),
|
|
|
|
Error::HostUnknown => Element::builder("host-unknown", Some(XMLNS)),
|
|
|
|
Error::ImproperAddressing => Element::builder("improper-addressing", Some(XMLNS)),
|
|
|
|
Error::InternalServerError => Element::builder("internal-server-error", Some(XMLNS)),
|
|
|
|
Error::InvalidFrom => Element::builder("invalid-from", Some(XMLNS)),
|
|
|
|
Error::InvalidId => Element::builder("invalid-id", Some(XMLNS)),
|
|
|
|
Error::InvalidNamespace => Element::builder("invalid-namespace", Some(XMLNS)),
|
|
|
|
Error::InvalidXml => Element::builder("invalid-xml", Some(XMLNS)),
|
|
|
|
Error::NotAuthorized => Element::builder("not-authorized", Some(XMLNS)),
|
|
|
|
Error::NotWellFormed => Element::builder("not-well-formed", Some(XMLNS)),
|
|
|
|
Error::PolicyViolation => Element::builder("policy-violation", Some(XMLNS)),
|
|
|
|
Error::RemoteConnectionFailed => {
|
|
|
|
Element::builder("remote-connection-failed", Some(XMLNS))
|
|
|
|
}
|
|
|
|
Error::Reset => Element::builder("reset", Some(XMLNS)),
|
|
|
|
Error::ResourceConstraint => Element::builder("resource-constraint", Some(XMLNS)),
|
|
|
|
Error::RestrictedXml => Element::builder("restricted-xml", Some(XMLNS)),
|
|
|
|
Error::SeeOtherHost(h) => {
|
|
|
|
Element::builder("see-other-host", Some(XMLNS)).push_text_opt(h.clone())
|
|
|
|
}
|
|
|
|
Error::SystemShutdown => Element::builder("system-shutdown", Some(XMLNS)),
|
|
|
|
Error::UndefinedCondition => Element::builder("undefined-condition", Some(XMLNS)),
|
|
|
|
Error::UnsupportedEncoding => Element::builder("unsupported-encoding", Some(XMLNS)),
|
|
|
|
Error::UnsupportedStanzaType => {
|
|
|
|
Element::builder("unsupported-stanza-type", Some(XMLNS))
|
|
|
|
}
|
|
|
|
Error::UnsupportedVersion => Element::builder("unsupported-version", Some(XMLNS)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-04 17:38:36 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2024-12-03 03:51:26 +00:00
|
|
|
pub struct Text {
|
|
|
|
text: Option<String>,
|
|
|
|
lang: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromElement for Text {
|
|
|
|
fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> {
|
|
|
|
element.check_name("text")?;
|
|
|
|
element.check_name(XMLNS)?;
|
|
|
|
|
|
|
|
let lang = element.attribute_opt_namespaced("lang", XML_NS)?;
|
|
|
|
let text = element.pop_value_opt()?;
|
|
|
|
|
|
|
|
Ok(Text { lang, text })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoElement for Text {
|
|
|
|
fn builder(&self) -> peanuts::element::ElementBuilder {
|
|
|
|
Element::builder("text", Some(XMLNS))
|
|
|
|
.push_attribute_opt_namespaced(XML_NS, "lang", self.lang.clone())
|
|
|
|
.push_text_opt(self.text.clone())
|
|
|
|
}
|
|
|
|
}
|