Derive Serialize, Deserialize impls for some enums

This commit is contained in:
Jonas Platte 2019-12-15 20:26:06 +01:00
parent 98f85df276
commit 1a3f6ed0b6
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
3 changed files with 61 additions and 146 deletions

View File

@ -1,16 +1,16 @@
use std::{ use std::{
borrow::Cow,
convert::Infallible, convert::Infallible,
fmt::{Debug, Display, Formatter, Result as FmtResult}, fmt::{Debug, Display, Formatter, Result as FmtResult},
}; };
use serde::{ use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
de::{DeserializeOwned, Error as SerdeError, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use serde_json::Value; use serde_json::Value;
/// The type of an event. /// The type of an event.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
// Cow<str> because deserialization sometimes needs to copy to unescape things
#[serde(from = "Cow<'_, str>", into = "String")]
pub enum EventType { pub enum EventType {
/// m.direct /// m.direct
Direct, Direct,
@ -38,49 +38,26 @@ impl Display for EventType {
} }
} }
impl<'a> From<&str> for EventType { impl<'a> From<Cow<'a, str>> for EventType {
fn from(s: &str) -> EventType { fn from(s: Cow<'a, str>) -> EventType {
match s { match &s as &str {
"m.direct" => EventType::Direct, "m.direct" => EventType::Direct,
"m.room.aliases" => EventType::RoomAliases, "m.room.aliases" => EventType::RoomAliases,
"m.room.redaction" => EventType::RoomRedaction, "m.room.redaction" => EventType::RoomRedaction,
event_type => EventType::Custom(event_type.to_string()), _ => EventType::Custom(s.into_owned()),
} }
} }
} }
impl Serialize for EventType { impl From<&str> for EventType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn from(s: &str) -> EventType {
where EventType::from(Cow::Borrowed(s))
S: Serializer,
{
serializer.serialize_str(&self.to_string())
} }
} }
impl<'de> Deserialize<'de> for EventType { impl From<EventType> for String {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn from(event_type: EventType) -> String {
where event_type.to_string()
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<E>(self, v: &str) -> Result<Self::Value, E>
where
E: SerdeError,
{
Ok(EventType::from(v))
}
}
deserializer.deserialize_str(EventTypeVisitor)
} }
} }

View File

@ -1,12 +1,12 @@
//! Types for the *m.key.verification.cancel* event. //! 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 ruma_events_macros::ruma_event;
use serde::{ use serde::{Deserialize, Serialize};
de::{Error as SerdeError, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
ruma_event! { ruma_event! {
/// Cancels a key verification process/request. /// 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. /// An error code for why the process/request was cancelled by the user.
/// ///
/// Custom error codes should use the Java package naming convention. /// Custom error codes should use the Java package naming convention.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
// Cow<str> because deserialization sometimes needs to copy to unescape things
#[serde(from = "Cow<'_, str>", into = "String")]
pub enum CancelCode { pub enum CancelCode {
/// The user cancelled the verification. /// The user cancelled the verification.
User, User,
@ -101,9 +103,9 @@ impl Display for CancelCode {
} }
} }
impl<'a> From<&str> for CancelCode { impl From<Cow<'_, str>> for CancelCode {
fn from(s: &str) -> CancelCode { fn from(s: Cow<'_, str>) -> CancelCode {
match s { match &s as &str {
"m.user" => CancelCode::User, "m.user" => CancelCode::User,
"m.timeout" => CancelCode::Timeout, "m.timeout" => CancelCode::Timeout,
"m.unknown_transaction" => CancelCode::UnknownTransaction, "m.unknown_transaction" => CancelCode::UnknownTransaction,
@ -113,43 +115,20 @@ impl<'a> From<&str> for CancelCode {
"m.user_mismatch" => CancelCode::UserMismatch, "m.user_mismatch" => CancelCode::UserMismatch,
"m.invalid_message" => CancelCode::InvalidMessage, "m.invalid_message" => CancelCode::InvalidMessage,
"m.accepted" => CancelCode::Accepted, "m.accepted" => CancelCode::Accepted,
cancel_code => CancelCode::Custom(cancel_code.to_string()), _ => CancelCode::Custom(s.into_owned()),
} }
} }
} }
impl Serialize for CancelCode { impl From<&str> for CancelCode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn from(s: &str) -> CancelCode {
where CancelCode::from(Cow::Borrowed(s))
S: Serializer,
{
serializer.serialize_str(&self.to_string())
} }
} }
impl<'de> Deserialize<'de> for CancelCode { impl From<CancelCode> for String {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn from(cancel_code: CancelCode) -> String {
where cancel_code.to_string()
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<E>(self, v: &str) -> Result<Self::Value, E>
where
E: SerdeError,
{
Ok(CancelCode::from(v))
}
}
deserializer.deserialize_str(CancelCodeVisitor)
} }
} }

View File

@ -115,6 +115,7 @@
#![allow(clippy::use_self)] #![allow(clippy::use_self)]
use std::{ use std::{
borrow::Cow,
convert::Infallible, convert::Infallible,
error::Error, error::Error,
fmt::{Debug, Display, Error as FmtError, Formatter, Result as FmtResult}, fmt::{Debug, Display, Error as FmtError, Formatter, Result as FmtResult},
@ -123,7 +124,7 @@ use std::{
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{ use serde::{
de::{DeserializeOwned, Error as SerdeError, MapAccess, Visitor}, de::{DeserializeOwned, MapAccess, Visitor},
ser::SerializeMap, ser::SerializeMap,
Deserialize, Deserializer, Serialize, Serializer, Deserialize, Deserializer, Serialize, Serializer,
}; };
@ -376,7 +377,9 @@ impl<'de> Deserialize<'de> for Empty {
} }
/// The type of an event. /// The type of an event.
#[derive(Clone, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
// Cow<str> because deserialization sometimes needs to copy to unescape things
#[serde(from = "Cow<'_, str>", into = "String")]
pub enum EventType { pub enum EventType {
/// m.call.answer /// m.call.answer
CallAnswer, CallAnswer,
@ -666,9 +669,9 @@ impl Display for EventType {
} }
} }
impl<'a> From<&str> for EventType { impl From<Cow<'_, str>> for EventType {
fn from(s: &str) -> EventType { fn from(s: Cow<'_, str>) -> EventType {
match s { match &s as &str {
"m.call.answer" => EventType::CallAnswer, "m.call.answer" => EventType::CallAnswer,
"m.call.candidates" => EventType::CallCandidates, "m.call.candidates" => EventType::CallCandidates,
"m.call.hangup" => EventType::CallHangup, "m.call.hangup" => EventType::CallHangup,
@ -712,48 +715,27 @@ impl<'a> From<&str> for EventType {
"m.sticker" => EventType::Sticker, "m.sticker" => EventType::Sticker,
"m.tag" => EventType::Tag, "m.tag" => EventType::Tag,
"m.typing" => EventType::Typing, "m.typing" => EventType::Typing,
event_type => EventType::Custom(event_type.to_string()), _ => EventType::Custom(s.into_owned()),
} }
} }
} }
impl Serialize for EventType { impl<'a> From<&str> for EventType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn from(s: &str) -> EventType {
where EventType::from(Cow::Borrowed(s))
S: Serializer,
{
serializer.serialize_str(&self.to_string())
} }
} }
impl<'de> Deserialize<'de> for EventType { impl From<EventType> for String {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn from(event_type: EventType) -> String {
where event_type.to_string()
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<E>(self, v: &str) -> Result<Self::Value, E>
where
E: SerdeError,
{
Ok(EventType::from(v))
}
}
deserializer.deserialize_str(EventTypeVisitor)
} }
} }
/// An encryption algorithm to be used to encrypt messages sent to a room. /// An encryption algorithm to be used to encrypt messages sent to a room.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
// Cow<str> because deserialization sometimes needs to copy to unescape things
#[serde(from = "Cow<'_, str>", into = "String")]
pub enum Algorithm { pub enum Algorithm {
/// Olm version 1 using Curve25519, AES-256, and SHA-256. /// Olm version 1 using Curve25519, AES-256, and SHA-256.
OlmV1Curve25519AesSha2, OlmV1Curve25519AesSha2,
@ -785,48 +767,25 @@ impl Display for Algorithm {
} }
} }
impl<'a> From<&str> for Algorithm { impl From<Cow<'_, str>> for Algorithm {
fn from(s: &str) -> Algorithm { fn from(s: Cow<'_, str>) -> Algorithm {
match s { match &s as &str {
"m.olm.v1.curve25519-aes-sha2" => Algorithm::OlmV1Curve25519AesSha2, "m.olm.v1.curve25519-aes-sha2" => Algorithm::OlmV1Curve25519AesSha2,
"m.megolm.v1.aes-sha2" => Algorithm::MegolmV1AesSha2, "m.megolm.v1.aes-sha2" => Algorithm::MegolmV1AesSha2,
algorithm => Algorithm::Custom(algorithm.to_string()), _ => Algorithm::Custom(s.into_owned()),
} }
} }
} }
impl Serialize for Algorithm { impl From<&str> for Algorithm {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn from(s: &str) -> Algorithm {
where Algorithm::from(Cow::Borrowed(s))
S: Serializer,
{
serializer.serialize_str(&self.to_string())
} }
} }
impl<'de> Deserialize<'de> for Algorithm { impl From<Algorithm> for String {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn from(algorithm: Algorithm) -> String {
where algorithm.to_string()
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<E>(self, v: &str) -> Result<Self::Value, E>
where
E: SerdeError,
{
Ok(Algorithm::from(v))
}
}
deserializer.deserialize_str(CancelCodeVisitor)
} }
} }