diff options
Diffstat (limited to 'stanza/src/xep_0060/errors.rs')
-rw-r--r-- | stanza/src/xep_0060/errors.rs | 282 |
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())), + }) + } +} |