aboutsummaryrefslogtreecommitdiffstats
path: root/stanza/src/xep_0060/errors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'stanza/src/xep_0060/errors.rs')
-rw-r--r--stanza/src/xep_0060/errors.rs282
1 files changed, 282 insertions, 0 deletions
diff --git a/stanza/src/xep_0060/errors.rs b/stanza/src/xep_0060/errors.rs
new file mode 100644
index 0000000..10d1483
--- /dev/null
+++ b/stanza/src/xep_0060/errors.rs
@@ -0,0 +1,282 @@
+use std::{fmt::Display, str::FromStr};
+
+use peanuts::{
+ element::{FromElement, IntoElement},
+ DeserializeError, Element,
+};
+use thiserror::Error;
+
+pub const XMLNS: &str = "http://jabber.org/protocol/pubsub#errors";
+
+#[derive(Error, Clone, Debug)]
+pub enum Error {
+ #[error("closed node")]
+ ClosedNode,
+ #[error("configuration required")]
+ ConfigurationRequired,
+ #[error("invalid jid")]
+ InvalidJID,
+ #[error("invalid options")]
+ InvalidOptions,
+ #[error("invalid payload")]
+ InvalidPayload,
+ #[error("invalid subscription id")]
+ InvalidSubID,
+ #[error("item forbidden")]
+ ItemForbidden,
+ #[error("item required")]
+ ItemRequired,
+ #[error("jid required")]
+ JIDRequired,
+ #[error("max items exceeded")]
+ MaxItemsExceeded,
+ #[error("max nodes exceeded")]
+ MaxNodesExceeded,
+ #[error("node id required")]
+ NodeIDRequired,
+ #[error("not in roster group")]
+ NotInRosterGroup,
+ #[error("not subscribed")]
+ NotSubscribed,
+ #[error("payload too big")]
+ PayloadTooBig,
+ #[error("payload required")]
+ PayloadRequired,
+ #[error("pending subscription")]
+ PendingSubscription,
+ #[error("precondition not met")]
+ PreconditionNotMet,
+ #[error("presence subscription required")]
+ PresenceSubscriptionRequired,
+ #[error("subscription id required")]
+ SubIDRequired,
+ #[error("too many subscriptions")]
+ TooManySubscriptions,
+ #[error("unsupported feature: {0}")]
+ Unsupported(Feature),
+ #[error("unsupported access mode")]
+ UnsupportedAccessModel,
+}
+
+impl FromElement for Error {
+ fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> {
+ match element.identify() {
+ (Some(XMLNS), "closed-node") => Ok(Self::ClosedNode),
+ (Some(XMLNS), "configuration-required") => Ok(Self::ConfigurationRequired),
+ (Some(XMLNS), "invalid-jid") => Ok(Self::InvalidJID),
+ (Some(XMLNS), "invalid-options") => Ok(Self::InvalidOptions),
+ (Some(XMLNS), "invalid-payload") => Ok(Self::InvalidPayload),
+ (Some(XMLNS), "invalid-subid") => Ok(Self::InvalidSubID),
+ (Some(XMLNS), "item-forbidden") => Ok(Self::ItemForbidden),
+ (Some(XMLNS), "item-required") => Ok(Self::ItemRequired),
+ (Some(XMLNS), "jid-required") => Ok(Self::JIDRequired),
+ (Some(XMLNS), "max-items-exceeded") => Ok(Self::MaxItemsExceeded),
+ (Some(XMLNS), "max-nodes-exceeded") => Ok(Self::MaxNodesExceeded),
+ (Some(XMLNS), "nodeid-required") => Ok(Self::NodeIDRequired),
+ (Some(XMLNS), "not-in-roster-group") => Ok(Self::NotInRosterGroup),
+ (Some(XMLNS), "not-subscribed") => Ok(Self::NotSubscribed),
+ (Some(XMLNS), "payload-too-big") => Ok(Self::PayloadTooBig),
+ (Some(XMLNS), "payload-required") => Ok(Self::PayloadRequired),
+ (Some(XMLNS), "pending-subscription") => Ok(Self::PendingSubscription),
+ (Some(XMLNS), "precondition-not-met") => Ok(Self::PreconditionNotMet),
+ (Some(XMLNS), "presence-subscription-required") => {
+ Ok(Self::PresenceSubscriptionRequired)
+ }
+ (Some(XMLNS), "subid-required") => Ok(Self::SubIDRequired),
+ (Some(XMLNS), "too-many-subscription") => Ok(Self::TooManySubscriptions),
+ (Some(XMLNS), "unsupported") => Ok(Self::Unsupported(element.attribute("feature")?)),
+ (Some(XMLNS), "unsupported-access-model") => Ok(Self::UnsupportedAccessModel),
+ _ => return Err(peanuts::DeserializeError::UnexpectedElement(element)),
+ }
+ }
+}
+
+impl IntoElement for Error {
+ fn builder(&self) -> peanuts::element::ElementBuilder {
+ match self {
+ Error::ClosedNode => Element::builder("closed-node", Some(XMLNS)),
+ Error::ConfigurationRequired => Element::builder("configuration-required", Some(XMLNS)),
+ Error::InvalidJID => Element::builder("invalid-jid", Some(XMLNS)),
+ Error::InvalidOptions => Element::builder("invalid-options", Some(XMLNS)),
+ Error::InvalidPayload => Element::builder("invalid-payload", Some(XMLNS)),
+ Error::InvalidSubID => Element::builder("invalid-subid", Some(XMLNS)),
+ Error::ItemForbidden => Element::builder("item-forbidden", Some(XMLNS)),
+ Error::ItemRequired => Element::builder("item-required", Some(XMLNS)),
+ Error::JIDRequired => Element::builder("jid-required", Some(XMLNS)),
+ Error::MaxItemsExceeded => Element::builder("max-items-exceeded", Some(XMLNS)),
+ Error::MaxNodesExceeded => Element::builder("max-nodes-exceeded", Some(XMLNS)),
+ Error::NodeIDRequired => Element::builder("node-id-required", Some(XMLNS)),
+ Error::NotInRosterGroup => Element::builder("not-in-roster-group", Some(XMLNS)),
+ Error::NotSubscribed => Element::builder("not-subscribed", Some(XMLNS)),
+ Error::PayloadTooBig => Element::builder("payload-too-big", Some(XMLNS)),
+ Error::PayloadRequired => Element::builder("payload-required", Some(XMLNS)),
+ Error::PendingSubscription => Element::builder("pending-subscription", Some(XMLNS)),
+ Error::PreconditionNotMet => Element::builder("precondition-not-met", Some(XMLNS)),
+ Error::PresenceSubscriptionRequired => {
+ Element::builder("presence-subscription-required", Some(XMLNS))
+ }
+ Error::SubIDRequired => Element::builder("subid-required", Some(XMLNS)),
+ Error::TooManySubscriptions => Element::builder("too-many-subscriptions", Some(XMLNS)),
+ Error::Unsupported(feature) => {
+ Element::builder("unsupported", Some(XMLNS)).push_attribute("feature", feature)
+ }
+ Error::UnsupportedAccessModel => {
+ Element::builder("unsupported-access-model", Some(XMLNS))
+ }
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum Feature {
+ AccessAuthorize,
+ AccessOpen,
+ AccessPresence,
+ AccessRoster,
+ AccessWhitelist,
+ AutoCreate,
+ AutoSubscribe,
+ Collections,
+ ConfigNode,
+ CreateAndConfigure,
+ CreateNodes,
+ DeleteItems,
+ DeleteNodes,
+ FilteredNotifications,
+ GetPending,
+ InstantNodes,
+ ItemIDs,
+ LastPublished,
+ LeasedSubscription,
+ ManageSubscriptions,
+ MemberAffiliation,
+ MetaData,
+ ModifyAffiliations,
+ MultiCollection,
+ MultiItems,
+ MultiSubscribe,
+ OutcastAffiliation,
+ PersistentItems,
+ PresenceNotifications,
+ PresenceSubscribe,
+ Publish,
+ PublishOptions,
+ PublishOnlyAffiliation,
+ PublisherAffiliation,
+ PurgeNodes,
+ RetractItems,
+ RetrieveAffiliations,
+ RetrieveDefault,
+ RetrieveDefaultSub,
+ RetrieveItems,
+ RetrieveSubscriptions,
+ Subscribe,
+ SubscriptionOptions,
+ SubscriptionNotifications,
+}
+
+impl Display for Feature {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let str = match self {
+ Feature::AccessAuthorize => "access-authorize",
+ Feature::AccessOpen => "access-open",
+ Feature::AccessPresence => "access-presence",
+ Feature::AccessRoster => "access-roster",
+ Feature::AccessWhitelist => "access-whitelist",
+ Feature::AutoCreate => "auto-create",
+ Feature::AutoSubscribe => "auto-subscribe",
+ Feature::Collections => "collections",
+ Feature::ConfigNode => "config-node",
+ Feature::CreateAndConfigure => "create-and-configure",
+ Feature::CreateNodes => "create-nodes",
+ Feature::DeleteItems => "delete-items",
+ Feature::DeleteNodes => "delete-nodes",
+ Feature::FilteredNotifications => "filtered-notifications",
+ Feature::GetPending => "get-pending",
+ Feature::InstantNodes => "instant-nodes",
+ Feature::ItemIDs => "item-ids",
+ Feature::LastPublished => "last-published",
+ Feature::LeasedSubscription => "leased-subscription",
+ Feature::ManageSubscriptions => "manage-subscriptions",
+ Feature::MemberAffiliation => "member-affiliation",
+ Feature::MetaData => "meta-data",
+ Feature::ModifyAffiliations => "modify-affiliations",
+ Feature::MultiCollection => "multi-collection",
+ Feature::MultiItems => "multi-items",
+ Feature::MultiSubscribe => "multi-subscribe",
+ Feature::OutcastAffiliation => "outcast-affiliation",
+ Feature::PersistentItems => "persistent-items",
+ Feature::PresenceNotifications => "presence-notifications",
+ Feature::PresenceSubscribe => "presence-subscribe",
+ Feature::Publish => "publish",
+ Feature::PublishOptions => "publish-options",
+ Feature::PublishOnlyAffiliation => "publish-only-affiliation",
+ Feature::PublisherAffiliation => "publisher-affiliation",
+ Feature::PurgeNodes => "purge-nodes",
+ Feature::RetractItems => "retract-items",
+ Feature::RetrieveAffiliations => "retrieve-affiliations",
+ Feature::RetrieveDefault => "retrieve-default",
+ Feature::RetrieveDefaultSub => "retrieve-default-sub",
+ Feature::RetrieveItems => "retrieve-items",
+ Feature::RetrieveSubscriptions => "retrieve-subscriptions",
+ Feature::Subscribe => "subscribe",
+ Feature::SubscriptionOptions => "subscription-options",
+ Feature::SubscriptionNotifications => "subscription-notifications",
+ };
+ f.write_str(str)
+ }
+}
+
+impl FromStr for Feature {
+ type Err = DeserializeError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "access-authorize" => Feature::AccessAuthorize,
+ "access-open" => Feature::AccessOpen,
+ "access-presence" => Feature::AccessPresence,
+ "access-roster" => Feature::AccessRoster,
+ "access-whitelist" => Feature::AccessWhitelist,
+ "auto-create" => Feature::AutoCreate,
+ "auto-subscribe" => Feature::AutoSubscribe,
+ "collections" => Feature::Collections,
+ "config-node" => Feature::ConfigNode,
+ "create-and-configure" => Feature::CreateAndConfigure,
+ "create-nodes" => Feature::CreateNodes,
+ "delete-items" => Feature::DeleteItems,
+ "delete-nodes" => Feature::DeleteNodes,
+ "filtered-notifications" => Feature::FilteredNotifications,
+ "get-pending" => Feature::GetPending,
+ "instant-nodes" => Feature::InstantNodes,
+ "item-ids" => Feature::ItemIDs,
+ "last-published" => Feature::LastPublished,
+ "leased-subscription" => Feature::LeasedSubscription,
+ "manage-subscriptions" => Feature::ManageSubscriptions,
+ "member-affiliation" => Feature::MemberAffiliation,
+ "meta-data" => Feature::MetaData,
+ "modify-affiliations" => Feature::ModifyAffiliations,
+ "multi-collection" => Feature::MultiCollection,
+ "multi-items" => Feature::MultiItems,
+ "multi-subscribe" => Feature::MultiSubscribe,
+ "outcast-affiliation" => Feature::OutcastAffiliation,
+ "persistent-items" => Feature::PersistentItems,
+ "presence-notifications" => Feature::PresenceNotifications,
+ "presence-subscribe" => Feature::PresenceSubscribe,
+ "publish" => Feature::Publish,
+ "publish-options" => Feature::PublishOptions,
+ "publish-only-affiliation" => Feature::PublishOnlyAffiliation,
+ "publisher-affiliation" => Feature::PublisherAffiliation,
+ "purge-nodes" => Feature::PurgeNodes,
+ "retract-items" => Feature::RetractItems,
+ "retrieve-affiliations" => Feature::RetrieveAffiliations,
+ "retrieve-default" => Feature::RetrieveDefault,
+ "retrieve-default-sub" => Feature::RetrieveDefaultSub,
+ "retrieve-items" => Feature::RetrieveItems,
+ "retrieve-subscriptions" => Feature::RetrieveSubscriptions,
+ "subscribe" => Feature::Subscribe,
+ "subscription-options" => Feature::SubscriptionOptions,
+ "subscription-notifications" => Feature::SubscriptionNotifications,
+ s => return Err(DeserializeError::FromStr(s.to_owned())),
+ })
+ }
+}