diff --git a/ruma-events-macros/tests/ruma_events_macros.rs b/ruma-events-macros/tests/ruma_events_macros.rs index 16508be1..9548b3ec 100644 --- a/ruma-events-macros/tests/ruma_events_macros.rs +++ b/ruma-events-macros/tests/ruma_events_macros.rs @@ -1,16 +1,16 @@ use std::{ + borrow::Cow, convert::Infallible, fmt::{Debug, Display, Formatter, Result as FmtResult}, }; -use serde::{ - de::{DeserializeOwned, Error as SerdeError, Visitor}, - Deserialize, Deserializer, Serialize, Serializer, -}; +use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize}; use serde_json::Value; /// The type of an event. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +// Cow because deserialization sometimes needs to copy to unescape things +#[serde(from = "Cow<'_, str>", into = "String")] pub enum EventType { /// m.direct Direct, @@ -38,49 +38,26 @@ impl Display for EventType { } } -impl<'a> From<&str> for EventType { - fn from(s: &str) -> EventType { - match s { +impl<'a> From> for EventType { + fn from(s: Cow<'a, str>) -> EventType { + match &s as &str { "m.direct" => EventType::Direct, "m.room.aliases" => EventType::RoomAliases, "m.room.redaction" => EventType::RoomRedaction, - event_type => EventType::Custom(event_type.to_string()), + _ => EventType::Custom(s.into_owned()), } } } -impl Serialize for EventType { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.to_string()) +impl From<&str> for EventType { + fn from(s: &str) -> EventType { + EventType::from(Cow::Borrowed(s)) } } -impl<'de> Deserialize<'de> for EventType { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct EventTypeVisitor; - - impl<'de> Visitor<'de> for EventTypeVisitor { - type Value = EventType; - - fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult { - write!(formatter, "a Matrix event type as a string") - } - - fn visit_str(self, v: &str) -> Result - where - E: SerdeError, - { - Ok(EventType::from(v)) - } - } - - deserializer.deserialize_str(EventTypeVisitor) +impl From for String { + fn from(event_type: EventType) -> String { + event_type.to_string() } } diff --git a/src/key/verification/cancel.rs b/src/key/verification/cancel.rs index c281c0b7..41d88553 100644 --- a/src/key/verification/cancel.rs +++ b/src/key/verification/cancel.rs @@ -1,12 +1,12 @@ //! Types for the *m.key.verification.cancel* event. -use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::{ + borrow::Cow, + fmt::{Display, Formatter, Result as FmtResult}, +}; use ruma_events_macros::ruma_event; -use serde::{ - de::{Error as SerdeError, Visitor}, - Deserialize, Deserializer, Serialize, Serializer, -}; +use serde::{Deserialize, Serialize}; ruma_event! { /// Cancels a key verification process/request. @@ -33,7 +33,9 @@ ruma_event! { /// An error code for why the process/request was cancelled by the user. /// /// Custom error codes should use the Java package naming convention. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +// Cow because deserialization sometimes needs to copy to unescape things +#[serde(from = "Cow<'_, str>", into = "String")] pub enum CancelCode { /// The user cancelled the verification. User, @@ -101,9 +103,9 @@ impl Display for CancelCode { } } -impl<'a> From<&str> for CancelCode { - fn from(s: &str) -> CancelCode { - match s { +impl From> for CancelCode { + fn from(s: Cow<'_, str>) -> CancelCode { + match &s as &str { "m.user" => CancelCode::User, "m.timeout" => CancelCode::Timeout, "m.unknown_transaction" => CancelCode::UnknownTransaction, @@ -113,43 +115,20 @@ impl<'a> From<&str> for CancelCode { "m.user_mismatch" => CancelCode::UserMismatch, "m.invalid_message" => CancelCode::InvalidMessage, "m.accepted" => CancelCode::Accepted, - cancel_code => CancelCode::Custom(cancel_code.to_string()), + _ => CancelCode::Custom(s.into_owned()), } } } -impl Serialize for CancelCode { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.to_string()) +impl From<&str> for CancelCode { + fn from(s: &str) -> CancelCode { + CancelCode::from(Cow::Borrowed(s)) } } -impl<'de> Deserialize<'de> for CancelCode { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct CancelCodeVisitor; - - impl<'de> Visitor<'de> for CancelCodeVisitor { - type Value = CancelCode; - - fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult { - write!(formatter, "an `m.key.verification.cancel` code as a string") - } - - fn visit_str(self, v: &str) -> Result - where - E: SerdeError, - { - Ok(CancelCode::from(v)) - } - } - - deserializer.deserialize_str(CancelCodeVisitor) +impl From for String { + fn from(cancel_code: CancelCode) -> String { + cancel_code.to_string() } } diff --git a/src/lib.rs b/src/lib.rs index 039cf093..80258530 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,6 +115,7 @@ #![allow(clippy::use_self)] use std::{ + borrow::Cow, convert::Infallible, error::Error, fmt::{Debug, Display, Error as FmtError, Formatter, Result as FmtResult}, @@ -123,7 +124,7 @@ use std::{ use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ - de::{DeserializeOwned, Error as SerdeError, MapAccess, Visitor}, + de::{DeserializeOwned, MapAccess, Visitor}, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer, }; @@ -376,7 +377,9 @@ impl<'de> Deserialize<'de> for Empty { } /// The type of an event. -#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] +// Cow because deserialization sometimes needs to copy to unescape things +#[serde(from = "Cow<'_, str>", into = "String")] pub enum EventType { /// m.call.answer CallAnswer, @@ -666,9 +669,9 @@ impl Display for EventType { } } -impl<'a> From<&str> for EventType { - fn from(s: &str) -> EventType { - match s { +impl From> for EventType { + fn from(s: Cow<'_, str>) -> EventType { + match &s as &str { "m.call.answer" => EventType::CallAnswer, "m.call.candidates" => EventType::CallCandidates, "m.call.hangup" => EventType::CallHangup, @@ -712,48 +715,27 @@ impl<'a> From<&str> for EventType { "m.sticker" => EventType::Sticker, "m.tag" => EventType::Tag, "m.typing" => EventType::Typing, - event_type => EventType::Custom(event_type.to_string()), + _ => EventType::Custom(s.into_owned()), } } } -impl Serialize for EventType { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.to_string()) +impl<'a> From<&str> for EventType { + fn from(s: &str) -> EventType { + EventType::from(Cow::Borrowed(s)) } } -impl<'de> Deserialize<'de> for EventType { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct EventTypeVisitor; - - impl<'de> Visitor<'de> for EventTypeVisitor { - type Value = EventType; - - fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult { - write!(formatter, "a Matrix event type as a string") - } - - fn visit_str(self, v: &str) -> Result - where - E: SerdeError, - { - Ok(EventType::from(v)) - } - } - - deserializer.deserialize_str(EventTypeVisitor) +impl From for String { + fn from(event_type: EventType) -> String { + event_type.to_string() } } /// An encryption algorithm to be used to encrypt messages sent to a room. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +// Cow because deserialization sometimes needs to copy to unescape things +#[serde(from = "Cow<'_, str>", into = "String")] pub enum Algorithm { /// Olm version 1 using Curve25519, AES-256, and SHA-256. OlmV1Curve25519AesSha2, @@ -785,48 +767,25 @@ impl Display for Algorithm { } } -impl<'a> From<&str> for Algorithm { - fn from(s: &str) -> Algorithm { - match s { +impl From> for Algorithm { + fn from(s: Cow<'_, str>) -> Algorithm { + match &s as &str { "m.olm.v1.curve25519-aes-sha2" => Algorithm::OlmV1Curve25519AesSha2, "m.megolm.v1.aes-sha2" => Algorithm::MegolmV1AesSha2, - algorithm => Algorithm::Custom(algorithm.to_string()), + _ => Algorithm::Custom(s.into_owned()), } } } -impl Serialize for Algorithm { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.to_string()) +impl From<&str> for Algorithm { + fn from(s: &str) -> Algorithm { + Algorithm::from(Cow::Borrowed(s)) } } -impl<'de> Deserialize<'de> for Algorithm { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct CancelCodeVisitor; - - impl<'de> Visitor<'de> for CancelCodeVisitor { - type Value = Algorithm; - - fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult { - write!(formatter, "an encryption algorithm code as a string") - } - - fn visit_str(self, v: &str) -> Result - where - E: SerdeError, - { - Ok(Algorithm::from(v)) - } - } - - deserializer.deserialize_str(CancelCodeVisitor) +impl From for String { + fn from(algorithm: Algorithm) -> String { + algorithm.to_string() } }