Use new macros for existing future-compatible enums

This commit is contained in:
Jonas Platte 2020-10-31 21:22:29 +01:00
parent 1f8e8c2e93
commit 70a12864ef
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
7 changed files with 110 additions and 258 deletions

View File

@ -7,6 +7,7 @@ use std::{
};
use js_int::UInt;
use ruma_common::{DeserializeFromCowStr, FromString};
use serde::{
de::{self, Deserialize, Deserializer, MapAccess, Visitor},
ser::{self, Serialize, SerializeMap, Serializer},
@ -207,96 +208,76 @@ impl<'de> Visitor<'de> for ErrorKindVisitor {
}
}
// FIXME: Derive FromString once available
// FIXME: Add `M_FOO_BAR` as a naming scheme in StringEnum and remove rename attributes.
#[derive(FromString, DeserializeFromCowStr)]
enum ErrCode {
#[ruma_enum(rename = "M_FORBIDDEN")]
Forbidden,
#[ruma_enum(rename = "M_UNKNOWN_TOKEN")]
UnknownToken,
#[ruma_enum(rename = "M_MISSING_TOKEN")]
MissingToken,
#[ruma_enum(rename = "M_BAD_JSON")]
BadJson,
#[ruma_enum(rename = "M_NOT_JSON")]
NotJson,
#[ruma_enum(rename = "M_NOT_FOUND")]
NotFound,
#[ruma_enum(rename = "M_LIMIT_EXCEEDED")]
LimitExceeded,
#[ruma_enum(rename = "M_UNKNOWN")]
Unknown,
#[ruma_enum(rename = "M_UNRECOGNIZED")]
Unrecognized,
#[ruma_enum(rename = "M_UNAUTHORIZED")]
Unauthorized,
#[ruma_enum(rename = "M_USER_DEACTIVATED")]
UserDeactivated,
#[ruma_enum(rename = "M_USER_IN_USE")]
UserInUse,
#[ruma_enum(rename = "M_INVALID_USERNAME")]
InvalidUsername,
#[ruma_enum(rename = "M_ROOM_IN_USE")]
RoomInUse,
#[ruma_enum(rename = "M_INVALID_ROOM_STATE")]
InvalidRoomState,
#[ruma_enum(rename = "M_THREEPID_IN_USE")]
ThreepidInUse,
#[ruma_enum(rename = "M_THREEPID_NOT_FOUND")]
ThreepidNotFound,
#[ruma_enum(rename = "M_THREEPID_AUTH_FAILED")]
ThreepidAuthFailed,
#[ruma_enum(rename = "M_THREEPID_DENIED")]
ThreepidDenied,
#[ruma_enum(rename = "M_SERVER_NOT_TRUSTED")]
ServerNotTrusted,
#[ruma_enum(rename = "M_UNSUPPORTED_ROOM_VERSION")]
UnsupportedRoomVersion,
#[ruma_enum(rename = "M_INCOMPATIBLE_ROOM_VERSION")]
IncompatibleRoomVersion,
#[ruma_enum(rename = "M_BAD_STATE")]
BadState,
#[ruma_enum(rename = "M_GUEST_ACCESS_FORBIDDEN")]
GuestAccessForbidden,
#[ruma_enum(rename = "M_CAPTCHA_NEEDED")]
CaptchaNeeded,
#[ruma_enum(rename = "M_CAPTCHA_INVALID")]
CaptchaInvalid,
#[ruma_enum(rename = "M_MISSING_PARAM")]
MissingParam,
#[ruma_enum(rename = "M_INVALID_PARAM")]
InvalidParam,
#[ruma_enum(rename = "M_TOO_LARGE")]
TooLarge,
#[ruma_enum(rename = "M_EXCLUSIVE")]
Exclusive,
#[ruma_enum(rename = "M_RESOURCE_LIMIT_EXCEEDED")]
ResourceLimitExceeded,
#[ruma_enum(rename = "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM")]
CannotLeaveServerNoticeRoom,
_Custom(String),
}
impl<'de> Deserialize<'de> for ErrCode {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = ruma_serde::deserialize_cow_str(deserializer)?;
Ok(s.into())
}
}
impl<T> From<T> for ErrCode
where
T: AsRef<str> + Into<String>,
{
fn from(s: T) -> Self {
match s.as_ref() {
"M_FORBIDDEN" => Self::Forbidden,
"M_UNKNOWN_TOKEN" => Self::UnknownToken,
"M_MISSING_TOKEN" => Self::MissingToken,
"M_BAD_JSON" => Self::BadJson,
"M_NOT_JSON" => Self::NotJson,
"M_NOT_FOUND" => Self::NotFound,
"M_LIMIT_EXCEEDED" => Self::LimitExceeded,
"M_UNKNOWN" => Self::Unknown,
"M_UNRECOGNIZED" => Self::Unrecognized,
"M_UNAUTHORIZED" => Self::Unauthorized,
"M_USER_DEACTIVATED" => Self::UserDeactivated,
"M_USER_IN_USE" => Self::UserInUse,
"M_INVALID_USERNAME" => Self::InvalidUsername,
"M_ROOM_IN_USE" => Self::RoomInUse,
"M_INVALID_ROOM_STATE" => Self::InvalidRoomState,
"M_THREEPID_IN_USE" => Self::ThreepidInUse,
"M_THREEPID_NOT_FOUND" => Self::ThreepidNotFound,
"M_THREEPID_AUTH_FAILED" => Self::ThreepidAuthFailed,
"M_THREEPID_DENIED" => Self::ThreepidDenied,
"M_SERVER_NOT_TRUSTED" => Self::ServerNotTrusted,
"M_UNSUPPORTED_ROOM_VERSION" => Self::UnsupportedRoomVersion,
"M_INCOMPATIBLE_ROOM_VERSION" => Self::IncompatibleRoomVersion,
"M_BAD_STATE" => Self::BadState,
"M_GUEST_ACCESS_FORBIDDEN" => Self::GuestAccessForbidden,
"M_CAPTCHA_NEEDED" => Self::CaptchaNeeded,
"M_CAPTCHA_INVALID" => Self::CaptchaInvalid,
"M_MISSING_PARAM" => Self::MissingParam,
"M_INVALID_PARAM" => Self::InvalidParam,
"M_TOO_LARGE" => Self::TooLarge,
"M_EXCLUSIVE" => Self::Exclusive,
"M_RESOURCE_LIMIT_EXCEEDED" => Self::ResourceLimitExceeded,
"M_CANNOT_LEAVE_SERVER_NOTICE_ROOM" => Self::CannotLeaveServerNoticeRoom,
_ => Self::_Custom(s.into()),
}
}
}
impl<'de> Deserialize<'de> for ErrorKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where

View File

@ -23,6 +23,8 @@ Breaking changes:
`room::member::SignedContent`.
* Remove the `EventType::Custom` variant. You can still check for custom event types by going
through `.as_str()`. This ensures that new event types doesn't break existing code.
* Remove the implementations of `From<EventType>` and `From<key::verification::cancel::CancelCode>`
for `String`. Use the `Display` or `ToString` implementations for those types instead.
Improvements:

View File

@ -1,281 +1,202 @@
use std::fmt::{Display, Formatter, Result as FmtResult};
use serde::{Deserialize, Serialize};
use ruma_common::StringEnum;
/// The type of an event.
///
/// This type can hold an arbitrary string. To check for events that are not available as a
/// documented variant here, use its string representation, obtained through `.as_str()`.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
// FIXME: Add `m.foo.bar` or `m.foo_bar` as a naming scheme in StringEnum and remove most rename
// attributes.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, StringEnum)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(from = "String", into = "String")]
pub enum EventType {
/// m.call.answer
#[ruma_enum(rename = "m.call.answer")]
CallAnswer,
/// m.call.candidates
#[ruma_enum(rename = "m.call.candidates")]
CallCandidates,
/// m.call.hangup
#[ruma_enum(rename = "m.call.hangup")]
CallHangup,
/// m.call.invite
#[ruma_enum(rename = "m.call.invite")]
CallInvite,
/// m.direct
#[ruma_enum(rename = "m.direct")]
Direct,
/// m.dummy
#[ruma_enum(rename = "m.dummy")]
Dummy,
/// m.forwarded_room_key
#[ruma_enum(rename = "m.forwarded_room_key")]
ForwardedRoomKey,
/// m.fully_read
#[ruma_enum(rename = "m.fully_read")]
FullyRead,
/// m.key.verification.accept
#[ruma_enum(rename = "m.key.verification.accept")]
KeyVerificationAccept,
/// m.key.verification.cancel
#[ruma_enum(rename = "m.key.verification.cancel")]
KeyVerificationCancel,
/// m.key.verification.key
#[ruma_enum(rename = "m.key.verification.key")]
KeyVerificationKey,
/// m.key.verification.mac
#[ruma_enum(rename = "m.key.verification.mac")]
KeyVerificationMac,
/// m.key.verification.request
#[ruma_enum(rename = "m.key.verification.request")]
KeyVerificationRequest,
/// m.key.verification.start
#[ruma_enum(rename = "m.key.verification.start")]
KeyVerificationStart,
/// m.ignored_user_list
#[ruma_enum(rename = "m.ignored_user_list")]
IgnoredUserList,
/// m.policy.rule.room
#[ruma_enum(rename = "m.policy.rule.room")]
PolicyRuleRoom,
/// m.policy.rule.server
#[ruma_enum(rename = "m.policy.rule.server")]
PolicyRuleServer,
/// m.policy.rule.user
#[ruma_enum(rename = "m.policy.rule.user")]
PolicyRuleUser,
/// m.presence
#[ruma_enum(rename = "m.presence")]
Presence,
/// m.push_rules
#[ruma_enum(rename = "m.push_rules")]
PushRules,
/// m.receipt
#[ruma_enum(rename = "m.receipt")]
Receipt,
/// m.room.aliases
#[ruma_enum(rename = "m.room.aliases")]
RoomAliases,
/// m.room.avatar
#[ruma_enum(rename = "m.room.avatar")]
RoomAvatar,
/// m.room.canonical_alias
#[ruma_enum(rename = "m.room.canonical_alias")]
RoomCanonicalAlias,
/// m.room.create
#[ruma_enum(rename = "m.room.create")]
RoomCreate,
/// m.room.encrypted
#[ruma_enum(rename = "m.room.encrypted")]
RoomEncrypted,
/// m.room.encryption
#[ruma_enum(rename = "m.room.encryption")]
RoomEncryption,
/// m.room.guest_access
#[ruma_enum(rename = "m.room.guest_access")]
RoomGuestAccess,
/// m.room.history_visibility
#[ruma_enum(rename = "m.room.history_visibility")]
RoomHistoryVisibility,
/// m.room.join_rules
#[ruma_enum(rename = "m.room.join_rules")]
RoomJoinRules,
/// m.room.member
#[ruma_enum(rename = "m.room.member")]
RoomMember,
/// m.room.message
#[ruma_enum(rename = "m.room.message")]
RoomMessage,
/// m.room.message.feedback
#[ruma_enum(rename = "m.room.message.feedback")]
RoomMessageFeedback,
/// m.room.name
#[ruma_enum(rename = "m.room.name")]
RoomName,
/// m.room.pinned_events
#[ruma_enum(rename = "m.room.pinned_events")]
RoomPinnedEvents,
/// m.room.power_levels
#[ruma_enum(rename = "m.room.power_levels")]
RoomPowerLevels,
/// m.room.redaction
#[ruma_enum(rename = "m.room.redaction")]
RoomRedaction,
/// m.room.server_acl
#[ruma_enum(rename = "m.room.server_acl")]
RoomServerAcl,
/// m.room.third_party_invite
#[ruma_enum(rename = "m.room.third_party_invite")]
RoomThirdPartyInvite,
/// m.room.tombstone
#[ruma_enum(rename = "m.room.tombstone")]
RoomTombstone,
/// m.room.topic
#[ruma_enum(rename = "m.room.topic")]
RoomTopic,
/// m.room_key
#[ruma_enum(rename = "m.room_key")]
RoomKey,
/// m.room_key_request
#[ruma_enum(rename = "m.room_key_request")]
RoomKeyRequest,
/// m.sticker
#[ruma_enum(rename = "m.sticker")]
Sticker,
/// m.tag
#[ruma_enum(rename = "m.tag")]
Tag,
/// m.typing
#[ruma_enum(rename = "m.typing")]
Typing,
#[doc(hidden)]
_Custom(String),
}
impl EventType {
/// Creates a string slice from this `EventType`.
pub fn as_str(&self) -> &str {
match *self {
EventType::CallAnswer => "m.call.answer",
EventType::CallCandidates => "m.call.candidates",
EventType::CallHangup => "m.call.hangup",
EventType::CallInvite => "m.call.invite",
EventType::Direct => "m.direct",
EventType::Dummy => "m.dummy",
EventType::ForwardedRoomKey => "m.forwarded_room_key",
EventType::FullyRead => "m.fully_read",
EventType::KeyVerificationAccept => "m.key.verification.accept",
EventType::KeyVerificationCancel => "m.key.verification.cancel",
EventType::KeyVerificationKey => "m.key.verification.key",
EventType::KeyVerificationMac => "m.key.verification.mac",
EventType::KeyVerificationRequest => "m.key.verification.request",
EventType::KeyVerificationStart => "m.key.verification.start",
EventType::IgnoredUserList => "m.ignored_user_list",
EventType::PolicyRuleRoom => "m.policy.rule.room",
EventType::PolicyRuleServer => "m.policy.rule.server",
EventType::PolicyRuleUser => "m.policy.rule.user",
EventType::Presence => "m.presence",
EventType::PushRules => "m.push_rules",
EventType::Receipt => "m.receipt",
EventType::RoomAliases => "m.room.aliases",
EventType::RoomAvatar => "m.room.avatar",
EventType::RoomCanonicalAlias => "m.room.canonical_alias",
EventType::RoomCreate => "m.room.create",
EventType::RoomEncrypted => "m.room.encrypted",
EventType::RoomEncryption => "m.room.encryption",
EventType::RoomGuestAccess => "m.room.guest_access",
EventType::RoomHistoryVisibility => "m.room.history_visibility",
EventType::RoomJoinRules => "m.room.join_rules",
EventType::RoomMember => "m.room.member",
EventType::RoomMessage => "m.room.message",
EventType::RoomMessageFeedback => "m.room.message.feedback",
EventType::RoomName => "m.room.name",
EventType::RoomPinnedEvents => "m.room.pinned_events",
EventType::RoomPowerLevels => "m.room.power_levels",
EventType::RoomRedaction => "m.room.redaction",
EventType::RoomServerAcl => "m.room.server_acl",
EventType::RoomThirdPartyInvite => "m.room.third_party_invite",
EventType::RoomTombstone => "m.room.tombstone",
EventType::RoomTopic => "m.room.topic",
EventType::RoomKey => "m.room_key",
EventType::RoomKeyRequest => "m.room_key_request",
EventType::Sticker => "m.sticker",
EventType::Tag => "m.tag",
EventType::Typing => "m.typing",
EventType::_Custom(ref event_type) => event_type,
}
}
}
impl Display for EventType {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str(self.as_str())
}
}
impl<T> From<T> for EventType
where
T: Into<String> + AsRef<str>,
{
fn from(s: T) -> EventType {
match s.as_ref() {
"m.call.answer" => EventType::CallAnswer,
"m.call.candidates" => EventType::CallCandidates,
"m.call.hangup" => EventType::CallHangup,
"m.call.invite" => EventType::CallInvite,
"m.direct" => EventType::Direct,
"m.dummy" => EventType::Dummy,
"m.forwarded_room_key" => EventType::ForwardedRoomKey,
"m.fully_read" => EventType::FullyRead,
"m.key.verification.accept" => EventType::KeyVerificationAccept,
"m.key.verification.cancel" => EventType::KeyVerificationCancel,
"m.key.verification.key" => EventType::KeyVerificationKey,
"m.key.verification.mac" => EventType::KeyVerificationMac,
"m.key.verification.request" => EventType::KeyVerificationRequest,
"m.key.verification.start" => EventType::KeyVerificationStart,
"m.ignored_user_list" => EventType::IgnoredUserList,
"m.policy.rule.room" => EventType::PolicyRuleRoom,
"m.policy.rule.server" => EventType::PolicyRuleServer,
"m.policy.rule.user" => EventType::PolicyRuleUser,
"m.presence" => EventType::Presence,
"m.push_rules" => EventType::PushRules,
"m.receipt" => EventType::Receipt,
"m.room.aliases" => EventType::RoomAliases,
"m.room.avatar" => EventType::RoomAvatar,
"m.room.canonical_alias" => EventType::RoomCanonicalAlias,
"m.room.create" => EventType::RoomCreate,
"m.room.encrypted" => EventType::RoomEncrypted,
"m.room.encryption" => EventType::RoomEncryption,
"m.room.guest_access" => EventType::RoomGuestAccess,
"m.room.history_visibility" => EventType::RoomHistoryVisibility,
"m.room.join_rules" => EventType::RoomJoinRules,
"m.room.member" => EventType::RoomMember,
"m.room.message" => EventType::RoomMessage,
"m.room.message.feedback" => EventType::RoomMessageFeedback,
"m.room.name" => EventType::RoomName,
"m.room.pinned_events" => EventType::RoomPinnedEvents,
"m.room.power_levels" => EventType::RoomPowerLevels,
"m.room.redaction" => EventType::RoomRedaction,
"m.room.server_acl" => EventType::RoomServerAcl,
"m.room.third_party_invite" => EventType::RoomThirdPartyInvite,
"m.room.tombstone" => EventType::RoomTombstone,
"m.room.topic" => EventType::RoomTopic,
"m.room_key" => EventType::RoomKey,
"m.room_key_request" => EventType::RoomKeyRequest,
"m.sticker" => EventType::Sticker,
"m.tag" => EventType::Tag,
"m.typing" => EventType::Typing,
_ => EventType::_Custom(s.into()),
}
}
}
impl From<EventType> for String {
fn from(event_type: EventType) -> String {
event_type.to_string()
}
}
#[cfg(test)]
mod tests {
use ruma_serde::test::serde_json_eq;

View File

@ -1,7 +1,6 @@
//! Types for the *m.key.verification.cancel* event.
use std::fmt::{Display, Formatter, Result as FmtResult};
use ruma_common::StringEnum;
use ruma_events_macros::BasicEventContent;
use serde::{Deserialize, Serialize};
@ -35,43 +34,52 @@ pub struct CancelEventContent {
/// This type can hold an arbitrary string. To check for events that are not
/// available as a documented variant here, use its string representation,
/// obtained through `.as_str()`.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
// FIXME: Add `m.foo_bar` as a naming scheme in StringEnum and remove rename attributes.
#[derive(Clone, Debug, PartialEq, StringEnum)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(from = "String", into = "String")]
pub enum CancelCode {
/// The user cancelled the verification.
#[ruma_enum(rename = "m.user")]
User,
/// The verification process timed out. Verification processes can define their own timeout
/// parameters.
#[ruma_enum(rename = "m.timeout")]
Timeout,
/// The device does not know about the given transaction ID.
#[ruma_enum(rename = "m.unknown_transaction")]
UnknownTransaction,
/// The device does not know how to handle the requested method.
///
/// This should be sent for *m.key.verification.start* messages and messages defined by
/// individual verification processes.
#[ruma_enum(rename = "m.unknown_method")]
UnknownMethod,
/// The device received an unexpected message.
///
/// Typically raised when one of the parties is handling the verification out of order.
#[ruma_enum(rename = "m.unexpected_message")]
UnexpectedMessage,
/// The key was not verified.
#[ruma_enum(rename = "m.key_mismatch")]
KeyMismatch,
/// The expected user did not match the user verified.
#[ruma_enum(rename = "m.user_mismatch")]
UserMismatch,
/// The message received was invalid.
#[ruma_enum(rename = "m.invalid_message")]
InvalidMessage,
/// An *m.key.verification.request* was accepted by a different device.
///
/// The device receiving this error can ignore the verification request.
#[ruma_enum(rename = "m.accepted")]
Accepted,
#[doc(hidden)]
@ -81,50 +89,7 @@ pub enum CancelCode {
impl CancelCode {
/// Creates a string slice from this `CancelCode`.
pub fn as_str(&self) -> &str {
match *self {
CancelCode::User => "m.user",
CancelCode::Timeout => "m.timeout",
CancelCode::UnknownTransaction => "m.unknown_transaction",
CancelCode::UnknownMethod => "m.unknown_method",
CancelCode::UnexpectedMessage => "m.unexpected_message",
CancelCode::KeyMismatch => "m.key_mismatch",
CancelCode::UserMismatch => "m.user_mismatch",
CancelCode::InvalidMessage => "m.invalid_message",
CancelCode::Accepted => "m.accepted",
CancelCode::_Custom(ref cancel_code) => cancel_code,
}
}
}
impl Display for CancelCode {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str(self.as_str())
}
}
impl<T> From<T> for CancelCode
where
T: Into<String> + AsRef<str>,
{
fn from(s: T) -> CancelCode {
match s.as_ref() {
"m.user" => CancelCode::User,
"m.timeout" => CancelCode::Timeout,
"m.unknown_transaction" => CancelCode::UnknownTransaction,
"m.unknown_method" => CancelCode::UnknownMethod,
"m.unexpected_message" => CancelCode::UnexpectedMessage,
"m.key_mismatch" => CancelCode::KeyMismatch,
"m.user_mismatch" => CancelCode::UserMismatch,
"m.invalid_message" => CancelCode::InvalidMessage,
"m.accepted" => CancelCode::Accepted,
_ => CancelCode::_Custom(s.into()),
}
}
}
impl From<CancelCode> for String {
fn from(cancel_code: CancelCode) -> String {
cancel_code.to_string()
self.as_ref()
}
}

View File

@ -1,8 +1,7 @@
//! Types for the *m.room.message* event.
use std::fmt;
use js_int::UInt;
use ruma_common::StringEnum;
use ruma_events_macros::MessageEventContent;
use ruma_identifiers::EventId;
use serde::{Deserialize, Serialize};
@ -313,11 +312,11 @@ pub enum LimitType {
/// This type can hold an arbitrary string. To check for events that are not
/// available as a documented variant here, use its string representation,
/// obtained through `.as_str()`.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, StringEnum)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum MessageFormat {
/// HTML.
#[serde(rename = "org.matrix.custom.html")]
#[ruma_enum(rename = "org.matrix.custom.html")]
Html,
#[doc(hidden)]
@ -327,16 +326,7 @@ pub enum MessageFormat {
impl MessageFormat {
/// Creates a string slice from this `MessageFormat`.
pub fn as_str(&self) -> &str {
match self {
Self::Html => "org.matrix.custom.html",
Self::_Custom(ref message_format) => message_format,
}
}
}
impl fmt::Display for MessageFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
self.as_ref()
}
}

View File

@ -26,6 +26,7 @@ serde = ["serde1", "ruma-identifiers-validation/serde"]
[dependencies]
either = { version = "1.5.3", optional = true }
rand = { version = "0.7.3", optional = true }
ruma-common-macros = { version = "0.2.0", path = "../ruma-common-macros" }
ruma-identifiers-macros = { version = "=0.17.4", path = "../ruma-identifiers-macros" }
ruma-identifiers-validation = { version = "0.1.1", path = "../ruma-identifiers-validation", default-features = false }
ruma-serde = { version = "0.2.3", path = "../ruma-serde" }

View File

@ -1,12 +1,8 @@
//! Matrix room version identifiers.
use std::{
cmp::Ordering,
convert::TryFrom,
fmt::{self, Display, Formatter},
str::FromStr,
};
use std::{cmp::Ordering, convert::TryFrom, str::FromStr};
use ruma_common_macros::DisplayAsRefStr;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
@ -27,7 +23,7 @@ use crate::Error;
/// Custom room versions or ones that were introduced into the specification after this code was
/// written are represented by a hidden enum variant. You can still construct them the same, and
/// check for them using one of `RoomVersionId`s `PartialEq` implementations or through `.as_str()`.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, DisplayAsRefStr)]
pub enum RoomVersionId {
/// A version 1 room.
Version1,
@ -54,6 +50,8 @@ pub enum RoomVersionId {
impl RoomVersionId {
/// Creates a string slice from this `RoomVersionId`.
pub fn as_str(&self) -> &str {
// FIXME: Add support for non-`str`-deref'ing types for fallback to AsRefStr derive and
// implement this function in terms of `AsRef<str>`
match &self {
Self::Version1 => "1",
Self::Version2 => "2",
@ -91,12 +89,6 @@ impl AsRef<str> for RoomVersionId {
}
}
impl Display for RoomVersionId {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_ref())
}
}
impl PartialOrd for RoomVersionId {
/// Compare the two given room version IDs by comparing their string representations.
///