Use Serde annotations instead of manual implementation for enums.
This commit is contained in:
parent
85578cf76f
commit
2eb07f5abd
@ -17,17 +17,12 @@ pub struct SessionDescription {
|
||||
}
|
||||
|
||||
/// The type of VoIP session description.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum SessionDescriptionType {
|
||||
/// An answer.
|
||||
#[serde(rename="answer")]
|
||||
Answer,
|
||||
/// An offer.
|
||||
#[serde(rename="offer")]
|
||||
Offer,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
SessionDescriptionType {
|
||||
Answer => "answer",
|
||||
Offer => "offer",
|
||||
}
|
||||
}
|
||||
|
35
src/lib.rs
35
src/lib.rs
@ -10,17 +10,12 @@ extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
use std::marker::PhantomData;
|
||||
use std::str::FromStr;
|
||||
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::{Deserialize, Deserializer, Error as SerdeError, Serialize, Serializer};
|
||||
use serde::de::Visitor as SerdeVisitor;
|
||||
use serde::de::Visitor;
|
||||
use serde_json::Value;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
pub mod call;
|
||||
pub mod presence;
|
||||
pub mod receipt;
|
||||
@ -160,14 +155,6 @@ pub struct StateEvent<C, E> where C: Deserialize + Serialize, E: Deserialize + S
|
||||
pub user_id: UserId,
|
||||
}
|
||||
|
||||
/// An error when attempting to convert a string to an enum that only accepts certain values.
|
||||
pub struct ParseError;
|
||||
|
||||
/// A Serde `Visitor` for deserializing various ruma-events enums.
|
||||
struct Visitor<T> where T: Deserialize + FromStr {
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl Display for EventType {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
let event_type_str = match *self {
|
||||
@ -240,7 +227,7 @@ impl Deserialize for EventType {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
struct EventTypeVisitor;
|
||||
|
||||
impl SerdeVisitor for EventTypeVisitor {
|
||||
impl Visitor for EventTypeVisitor {
|
||||
type Value = EventType;
|
||||
|
||||
fn visit_str<E>(&mut self, v: &str) -> Result<Self::Value, E> where E: SerdeError {
|
||||
@ -252,24 +239,6 @@ impl Deserialize for EventType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor<T> where T: Deserialize + FromStr {
|
||||
pub fn new() -> Visitor<T> {
|
||||
Visitor {
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SerdeVisitor for Visitor<T> where T: Deserialize + FromStr {
|
||||
type Value = T;
|
||||
|
||||
fn visit_str<E>(&mut self, v: &str) -> Result<Self::Value, E> where E: SerdeError {
|
||||
v.parse().map_err(|_| {
|
||||
E::invalid_value(v)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::{from_str, to_string};
|
||||
|
@ -1,60 +0,0 @@
|
||||
macro_rules! impl_enum {
|
||||
($name:ident { $($variant:ident => $s:expr,)+ }) => {
|
||||
impl ::std::fmt::Display for $name {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
|
||||
let variant = match *self {
|
||||
$($name::$variant => $s,)*
|
||||
};
|
||||
|
||||
write!(f, "{}", variant)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::str::FromStr for $name {
|
||||
type Err = $crate::ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
$($s => Ok($name::$variant),)*
|
||||
_ => Err($crate::ParseError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::serde::Serialize for $name {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: ::serde::Serializer {
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::serde::Deserialize for $name {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
|
||||
where D: ::serde::Deserializer {
|
||||
deserializer.deserialize_str($crate::Visitor::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod serialization_tests {
|
||||
use serde_json::{from_str, to_string};
|
||||
|
||||
use super::$name;
|
||||
|
||||
#[test]
|
||||
fn serialization_to_display_form() {
|
||||
$(assert_eq!(to_string(&$name::$variant).unwrap(), stringify!($s));)*
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialization_from_display_form() {
|
||||
$(assert_eq!(from_str::<$name>(stringify!($s)).unwrap(), $name::$variant);)*
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialization_fails_for_invalid_string_value() {
|
||||
assert!(from_str::<$name>(r#""invalid variant name""#).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -33,15 +33,18 @@ pub struct PresenceEventContent {
|
||||
}
|
||||
|
||||
/// A description of a user's connectivity and availability for chat.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum PresenceState {
|
||||
/// Disconnected from the service.
|
||||
#[serde(rename="offline")]
|
||||
Offline,
|
||||
|
||||
/// Connected to the service.
|
||||
#[serde(rename="online")]
|
||||
Online,
|
||||
|
||||
/// Connected to the service but not available for chat.
|
||||
#[serde(rename="unavailable")]
|
||||
Unavailable,
|
||||
}
|
||||
|
||||
@ -51,11 +54,3 @@ pub struct PresenceEventExtraContent {
|
||||
/// The unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
PresenceState {
|
||||
Offline => "offline",
|
||||
Online => "online",
|
||||
Unavailable => "unavailable",
|
||||
}
|
||||
}
|
||||
|
@ -16,18 +16,13 @@ pub struct GuestAccessEventContent {
|
||||
}
|
||||
|
||||
/// A policy for guest user access to a room.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum GuestAccess {
|
||||
/// Guests are allowed to join the room.
|
||||
#[serde(rename="can_join")]
|
||||
CanJoin,
|
||||
|
||||
/// Guests are not allowed to join the room.
|
||||
#[serde(rename="forbidden")]
|
||||
Forbidden,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
GuestAccess {
|
||||
CanJoin => "can_join",
|
||||
Forbidden => "forbidden",
|
||||
}
|
||||
}
|
||||
|
@ -14,32 +14,27 @@ pub struct HistoryVisibilityEventContent {
|
||||
}
|
||||
|
||||
/// Who can see a room's history.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum HistoryVisibility {
|
||||
/// Previous events are accessible to newly joined members from the point they were invited
|
||||
/// onwards. Events stop being accessible when the member's state changes to something other
|
||||
/// than *invite* or *join*.
|
||||
#[serde(rename="invited")]
|
||||
Invited,
|
||||
|
||||
/// Previous events are accessible to newly joined members from the point they joined the room
|
||||
/// onwards. Events stop being accessible when the member's state changes to something other
|
||||
/// than *join*.
|
||||
#[serde(rename="joined")]
|
||||
Joined,
|
||||
|
||||
/// Previous events are always accessible to newly joined members. All events in the room are
|
||||
/// accessible, even those sent when the member was not a part of the room.
|
||||
#[serde(rename="shared")]
|
||||
Shared,
|
||||
|
||||
/// All events while this is the `HistoryVisibility` value may be shared by any
|
||||
/// participating homeserver with anyone, regardless of whether they have ever joined the room.
|
||||
#[serde(rename="world_readable")]
|
||||
WorldReadable,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
HistoryVisibility {
|
||||
Invited => "invited",
|
||||
Joined => "joined",
|
||||
Shared => "shared",
|
||||
WorldReadable => "world_readable",
|
||||
}
|
||||
}
|
||||
|
@ -13,27 +13,22 @@ pub struct JoinRulesEventContent {
|
||||
}
|
||||
|
||||
/// The rule used for users wishing to join this room.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum JoinRule {
|
||||
/// A user who wishes to join the room must first receive an invite to the room from someone
|
||||
/// already inside of the room.
|
||||
#[serde(rename="invite")]
|
||||
Invite,
|
||||
|
||||
/// Reserved but not yet implemented by the Matrix specification.
|
||||
#[serde(rename="knock")]
|
||||
Knock,
|
||||
|
||||
/// Reserved but not yet implemented by the Matrix specification.
|
||||
#[serde(rename="private")]
|
||||
Private,
|
||||
|
||||
/// Anyone can join the room without any prior action.
|
||||
#[serde(rename="public")]
|
||||
Public,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
JoinRule {
|
||||
Invite => "invite",
|
||||
Knock => "knock",
|
||||
Private => "private",
|
||||
Public => "public",
|
||||
}
|
||||
}
|
||||
|
@ -37,21 +37,26 @@ pub struct MemberEventContent {
|
||||
}
|
||||
|
||||
/// The membership state of a user.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum MembershipState {
|
||||
/// The user is banned.
|
||||
#[serde(rename="ban")]
|
||||
Ban,
|
||||
|
||||
/// The user has been invited.
|
||||
#[serde(rename="invite")]
|
||||
Invite,
|
||||
|
||||
/// The user has joined.
|
||||
#[serde(rename="join")]
|
||||
Join,
|
||||
|
||||
/// The user has requested to join.
|
||||
#[serde(rename="knock")]
|
||||
Knock,
|
||||
|
||||
/// The user has left.
|
||||
#[serde(rename="leave")]
|
||||
Leave,
|
||||
}
|
||||
|
||||
@ -62,13 +67,3 @@ pub struct MemberEventExtraContent {
|
||||
#[serde(skip_serializing_if="Option::is_none")]
|
||||
pub invite_room_state: Option<Vec<StrippedState>>,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
MembershipState {
|
||||
Ban => "ban",
|
||||
Invite => "invite",
|
||||
Join => "join",
|
||||
Knock => "knock",
|
||||
Leave => "leave",
|
||||
}
|
||||
}
|
||||
|
@ -10,30 +10,38 @@ use super::ImageInfo;
|
||||
pub type MessageEvent = RoomEvent<MessageEventContent, ()>;
|
||||
|
||||
/// The message type of message event, e.g. `m.image` or `m.text`.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub enum MessageType {
|
||||
/// An audio message.
|
||||
#[serde(rename="m.audio")]
|
||||
Audio,
|
||||
|
||||
/// An emote message.
|
||||
#[serde(rename="m.emote")]
|
||||
Emote,
|
||||
|
||||
/// A file message.
|
||||
#[serde(rename="m.file")]
|
||||
File,
|
||||
|
||||
/// An image message.
|
||||
#[serde(rename="m.image")]
|
||||
Image,
|
||||
|
||||
/// A location message.
|
||||
#[serde(rename="m.location")]
|
||||
Location,
|
||||
|
||||
/// A notice message.
|
||||
#[serde(rename="m.notice")]
|
||||
Notice,
|
||||
|
||||
/// A text message.
|
||||
#[serde(rename="m.text")]
|
||||
Text,
|
||||
|
||||
/// A video message.
|
||||
#[serde(rename="m.video")]
|
||||
Video,
|
||||
}
|
||||
|
||||
@ -230,19 +238,6 @@ pub struct VideoInfo {
|
||||
pub w: Option<u64>,
|
||||
}
|
||||
|
||||
impl_enum! {
|
||||
MessageType {
|
||||
Audio => "m.audio",
|
||||
Emote => "m.emote",
|
||||
File => "m.file",
|
||||
Image => "m.image",
|
||||
Location => "m.location",
|
||||
Notice => "m.notice",
|
||||
Text => "m.text",
|
||||
Video => "m.video",
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for MessageEventContent {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
@ -342,7 +337,7 @@ impl Deserialize for MessageEventContent {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod message_event_content_serialization_tests {
|
||||
mod tests {
|
||||
use serde_json::{from_str, to_string};
|
||||
|
||||
use super::{AudioMessageEventContent, MessageType, MessageEventContent};
|
||||
|
Loading…
x
Reference in New Issue
Block a user