diff --git a/ruma-client-api/src/error/kind_serde.rs b/ruma-client-api/src/error/kind_serde.rs index 7c5ca0fa..01878333 100644 --- a/ruma-client-api/src/error/kind_serde.rs +++ b/ruma-client-api/src/error/kind_serde.rs @@ -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(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = ruma_serde::deserialize_cow_str(deserializer)?; - Ok(s.into()) - } -} - -impl From for ErrCode -where - T: AsRef + Into, -{ - 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(deserializer: D) -> Result where diff --git a/ruma-events/CHANGELOG.md b/ruma-events/CHANGELOG.md index fa1a3486..da5b0bb0 100644 --- a/ruma-events/CHANGELOG.md +++ b/ruma-events/CHANGELOG.md @@ -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` and `From` + for `String`. Use the `Display` or `ToString` implementations for those types instead. Improvements: diff --git a/ruma-events/src/event_type.rs b/ruma-events/src/event_type.rs index 21e8e721..f5afb87d 100644 --- a/ruma-events/src/event_type.rs +++ b/ruma-events/src/event_type.rs @@ -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 From for EventType -where - T: Into + AsRef, -{ - 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 for String { - fn from(event_type: EventType) -> String { - event_type.to_string() - } -} - #[cfg(test)] mod tests { use ruma_serde::test::serde_json_eq; diff --git a/ruma-events/src/key/verification/cancel.rs b/ruma-events/src/key/verification/cancel.rs index 9fb8f8c4..e729b845 100644 --- a/ruma-events/src/key/verification/cancel.rs +++ b/ruma-events/src/key/verification/cancel.rs @@ -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 From for CancelCode -where - T: Into + AsRef, -{ - 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 for String { - fn from(cancel_code: CancelCode) -> String { - cancel_code.to_string() + self.as_ref() } } diff --git a/ruma-events/src/room/message.rs b/ruma-events/src/room/message.rs index 6a7e5a55..178f8188 100644 --- a/ruma-events/src/room/message.rs +++ b/ruma-events/src/room/message.rs @@ -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() } } diff --git a/ruma-identifiers/Cargo.toml b/ruma-identifiers/Cargo.toml index 37e9f014..eeef7c23 100644 --- a/ruma-identifiers/Cargo.toml +++ b/ruma-identifiers/Cargo.toml @@ -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" } diff --git a/ruma-identifiers/src/room_version_id.rs b/ruma-identifiers/src/room_version_id.rs index d468f0d7..1841304a 100644 --- a/ruma-identifiers/src/room_version_id.rs +++ b/ruma-identifiers/src/room_version_id.rs @@ -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` match &self { Self::Version1 => "1", Self::Version2 => "2", @@ -91,12 +89,6 @@ impl AsRef 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. ///