Implement Deserialize and Serialize for collection types.
This commit is contained in:
parent
7aeca5829c
commit
56457e1bb4
@ -1,9 +1,7 @@
|
||||
//! Enums for heterogeneous collections of events, inclusive for every event type that implements
|
||||
//! the trait of the same name.
|
||||
|
||||
use CustomEvent;
|
||||
use CustomRoomEvent;
|
||||
use CustomStateEvent;
|
||||
use {CustomEvent, CustomRoomEvent, CustomStateEvent, EventType};
|
||||
use call::answer::AnswerEvent;
|
||||
use call::candidates::CandidatesEvent;
|
||||
use call::hangup::HangupEvent;
|
||||
@ -27,6 +25,9 @@ use room::topic::TopicEvent;
|
||||
use tag::TagEvent;
|
||||
use typing::TypingEvent;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Error as SerdeError, Serialize, Serializer};
|
||||
use serde_json::{Value, from_value};
|
||||
|
||||
/// A basic event, room event, or state event.
|
||||
pub enum Event {
|
||||
/// m.call.answer
|
||||
@ -155,6 +156,617 @@ pub enum StateEvent {
|
||||
CustomState(CustomStateEvent),
|
||||
}
|
||||
|
||||
impl Serialize for Event {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
Event::CallAnswer(ref event) => event.serialize(serializer),
|
||||
Event::CallCandidates(ref event) => event.serialize(serializer),
|
||||
Event::CallHangup(ref event) => event.serialize(serializer),
|
||||
Event::CallInvite(ref event) => event.serialize(serializer),
|
||||
Event::Presence(ref event) => event.serialize(serializer),
|
||||
Event::Receipt(ref event) => event.serialize(serializer),
|
||||
Event::RoomAliases(ref event) => event.serialize(serializer),
|
||||
Event::RoomAvatar(ref event) => event.serialize(serializer),
|
||||
Event::RoomCanonicalAlias(ref event) => event.serialize(serializer),
|
||||
Event::RoomCreate(ref event) => event.serialize(serializer),
|
||||
Event::RoomGuestAccess(ref event) => event.serialize(serializer),
|
||||
Event::RoomHistoryVisibility(ref event) => event.serialize(serializer),
|
||||
Event::RoomJoinRules(ref event) => event.serialize(serializer),
|
||||
Event::RoomMember(ref event) => event.serialize(serializer),
|
||||
Event::RoomMessage(ref event) => event.serialize(serializer),
|
||||
Event::RoomName(ref event) => event.serialize(serializer),
|
||||
Event::RoomPowerLevels(ref event) => event.serialize(serializer),
|
||||
Event::RoomRedaction(ref event) => event.serialize(serializer),
|
||||
Event::RoomThirdPartyInvite(ref event) => event.serialize(serializer),
|
||||
Event::RoomTopic(ref event) => event.serialize(serializer),
|
||||
Event::Tag(ref event) => event.serialize(serializer),
|
||||
Event::Typing(ref event) => event.serialize(serializer),
|
||||
Event::Custom(ref event) => event.serialize(serializer),
|
||||
Event::CustomRoom(ref event) => event.serialize(serializer),
|
||||
Event::CustomState(ref event) => event.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for Event {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
let value: Value = try!(Deserialize::deserialize(deserializer));
|
||||
|
||||
let event_type_value = match value.find("type") {
|
||||
Some(value) => value.clone(),
|
||||
None => return Err(D::Error::missing_field("type")),
|
||||
};
|
||||
|
||||
let event_type = match from_value::<EventType>(event_type_value.clone()) {
|
||||
Ok(event_type) => event_type,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
match event_type {
|
||||
EventType::CallAnswer => {
|
||||
let event = match from_value::<AnswerEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::CallAnswer(event))
|
||||
}
|
||||
EventType::CallCandidates => {
|
||||
let event = match from_value::<CandidatesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::CallCandidates(event))
|
||||
}
|
||||
EventType::CallHangup => {
|
||||
let event = match from_value::<HangupEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::CallHangup(event))
|
||||
}
|
||||
EventType::CallInvite => {
|
||||
let event = match from_value::<InviteEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::CallInvite(event))
|
||||
}
|
||||
EventType::Presence => {
|
||||
let event = match from_value::<PresenceEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Presence(event))
|
||||
}
|
||||
EventType::Receipt => {
|
||||
let event = match from_value::<ReceiptEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Receipt(event))
|
||||
}
|
||||
EventType::RoomAliases => {
|
||||
let event = match from_value::<AliasesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomAliases(event))
|
||||
}
|
||||
EventType::RoomAvatar => {
|
||||
let event = match from_value::<AvatarEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomAvatar(event))
|
||||
}
|
||||
EventType::RoomCanonicalAlias => {
|
||||
let event = match from_value::<CanonicalAliasEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomCanonicalAlias(event))
|
||||
}
|
||||
EventType::RoomCreate => {
|
||||
let event = match from_value::<CreateEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomCreate(event))
|
||||
}
|
||||
EventType::RoomGuestAccess => {
|
||||
let event = match from_value::<GuestAccessEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomGuestAccess(event))
|
||||
}
|
||||
EventType::RoomHistoryVisibility => {
|
||||
let event = match from_value::<HistoryVisibilityEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomHistoryVisibility(event))
|
||||
}
|
||||
EventType::RoomJoinRules => {
|
||||
let event = match from_value::<JoinRulesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomJoinRules(event))
|
||||
}
|
||||
EventType::RoomMember => {
|
||||
let event = match from_value::<MemberEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomMember(event))
|
||||
}
|
||||
EventType::RoomMessage => {
|
||||
let event = match from_value::<MessageEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomMessage(event))
|
||||
}
|
||||
EventType::RoomName => {
|
||||
let event = match from_value::<NameEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomName(event))
|
||||
}
|
||||
EventType::RoomPowerLevels => {
|
||||
let event = match from_value::<PowerLevelsEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomPowerLevels(event))
|
||||
}
|
||||
EventType::RoomRedaction => {
|
||||
let event = match from_value::<RedactionEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomRedaction(event))
|
||||
}
|
||||
EventType::RoomThirdPartyInvite => {
|
||||
let event = match from_value::<ThirdPartyInviteEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomThirdPartyInvite(event))
|
||||
}
|
||||
EventType::RoomTopic => {
|
||||
let event = match from_value::<TopicEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::RoomTopic(event))
|
||||
}
|
||||
EventType::Tag => {
|
||||
let event = match from_value::<TagEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Tag(event))
|
||||
}
|
||||
EventType::Typing => {
|
||||
let event = match from_value::<TypingEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Typing(event))
|
||||
}
|
||||
EventType::Custom(_) => {
|
||||
if value.find("state_key").is_some() {
|
||||
let event = match from_value::<CustomStateEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::CustomState(event))
|
||||
} else if value.find("event_id").is_some() && value.find("room_id").is_some() &&
|
||||
value.find("sender").is_some() {
|
||||
let event = match from_value::<CustomRoomEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::CustomRoom(event))
|
||||
} else {
|
||||
let event = match from_value::<CustomEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Custom(event))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for RoomEvent {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
RoomEvent::CallAnswer(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CallCandidates(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CallHangup(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CallInvite(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomAliases(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomAvatar(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomCanonicalAlias(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomCreate(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomGuestAccess(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomHistoryVisibility(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomJoinRules(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomMember(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomMessage(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomName(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomPowerLevels(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomRedaction(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomThirdPartyInvite(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomTopic(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CustomRoom(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CustomState(ref event) => event.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for RoomEvent {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
let value: Value = try!(Deserialize::deserialize(deserializer));
|
||||
|
||||
let event_type_value = match value.find("type") {
|
||||
Some(value) => value.clone(),
|
||||
None => return Err(D::Error::missing_field("type")),
|
||||
};
|
||||
|
||||
let event_type = match from_value::<EventType>(event_type_value.clone()) {
|
||||
Ok(event_type) => event_type,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
match event_type {
|
||||
EventType::CallAnswer => {
|
||||
let event = match from_value::<AnswerEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallAnswer(event))
|
||||
}
|
||||
EventType::CallCandidates => {
|
||||
let event = match from_value::<CandidatesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallCandidates(event))
|
||||
}
|
||||
EventType::CallHangup => {
|
||||
let event = match from_value::<HangupEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallHangup(event))
|
||||
}
|
||||
EventType::CallInvite => {
|
||||
let event = match from_value::<InviteEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallInvite(event))
|
||||
}
|
||||
EventType::RoomAliases => {
|
||||
let event = match from_value::<AliasesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomAliases(event))
|
||||
}
|
||||
EventType::RoomAvatar => {
|
||||
let event = match from_value::<AvatarEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomAvatar(event))
|
||||
}
|
||||
EventType::RoomCanonicalAlias => {
|
||||
let event = match from_value::<CanonicalAliasEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomCanonicalAlias(event))
|
||||
}
|
||||
EventType::RoomCreate => {
|
||||
let event = match from_value::<CreateEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomCreate(event))
|
||||
}
|
||||
EventType::RoomGuestAccess => {
|
||||
let event = match from_value::<GuestAccessEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomGuestAccess(event))
|
||||
}
|
||||
EventType::RoomHistoryVisibility => {
|
||||
let event = match from_value::<HistoryVisibilityEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomHistoryVisibility(event))
|
||||
}
|
||||
EventType::RoomJoinRules => {
|
||||
let event = match from_value::<JoinRulesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomJoinRules(event))
|
||||
}
|
||||
EventType::RoomMember => {
|
||||
let event = match from_value::<MemberEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomMember(event))
|
||||
}
|
||||
EventType::RoomMessage => {
|
||||
let event = match from_value::<MessageEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomMessage(event))
|
||||
}
|
||||
EventType::RoomName => {
|
||||
let event = match from_value::<NameEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomName(event))
|
||||
}
|
||||
EventType::RoomPowerLevels => {
|
||||
let event = match from_value::<PowerLevelsEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomPowerLevels(event))
|
||||
}
|
||||
EventType::RoomRedaction => {
|
||||
let event = match from_value::<RedactionEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomRedaction(event))
|
||||
}
|
||||
EventType::RoomThirdPartyInvite => {
|
||||
let event = match from_value::<ThirdPartyInviteEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomThirdPartyInvite(event))
|
||||
}
|
||||
EventType::RoomTopic => {
|
||||
let event = match from_value::<TopicEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomTopic(event))
|
||||
}
|
||||
EventType::Custom(_) => {
|
||||
if value.find("state_key").is_some() {
|
||||
let event = match from_value::<CustomStateEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CustomState(event))
|
||||
} else {
|
||||
let event = match from_value::<CustomRoomEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CustomRoom(event))
|
||||
}
|
||||
}
|
||||
EventType::Presence | EventType::Receipt | EventType::Tag | EventType::Typing => {
|
||||
return Err(D::Error::custom("not a room event".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for StateEvent {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
StateEvent::RoomAliases(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomAvatar(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomCanonicalAlias(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomCreate(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomGuestAccess(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomHistoryVisibility(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomJoinRules(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomMember(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomName(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomPowerLevels(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomThirdPartyInvite(ref event) => event.serialize(serializer),
|
||||
StateEvent::RoomTopic(ref event) => event.serialize(serializer),
|
||||
StateEvent::CustomState(ref event) => event.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for StateEvent {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
let value: Value = try!(Deserialize::deserialize(deserializer));
|
||||
|
||||
let event_type_value = match value.find("type") {
|
||||
Some(value) => value.clone(),
|
||||
None => return Err(D::Error::missing_field("type")),
|
||||
};
|
||||
|
||||
let event_type = match from_value::<EventType>(event_type_value.clone()) {
|
||||
Ok(event_type) => event_type,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
match event_type {
|
||||
EventType::RoomAliases => {
|
||||
let event = match from_value::<AliasesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomAliases(event))
|
||||
}
|
||||
EventType::RoomAvatar => {
|
||||
let event = match from_value::<AvatarEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomAvatar(event))
|
||||
}
|
||||
EventType::RoomCanonicalAlias => {
|
||||
let event = match from_value::<CanonicalAliasEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomCanonicalAlias(event))
|
||||
}
|
||||
EventType::RoomCreate => {
|
||||
let event = match from_value::<CreateEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomCreate(event))
|
||||
}
|
||||
EventType::RoomGuestAccess => {
|
||||
let event = match from_value::<GuestAccessEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomGuestAccess(event))
|
||||
}
|
||||
EventType::RoomHistoryVisibility => {
|
||||
let event = match from_value::<HistoryVisibilityEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomHistoryVisibility(event))
|
||||
}
|
||||
EventType::RoomJoinRules => {
|
||||
let event = match from_value::<JoinRulesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomJoinRules(event))
|
||||
}
|
||||
EventType::RoomMember => {
|
||||
let event = match from_value::<MemberEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomMember(event))
|
||||
}
|
||||
EventType::RoomName => {
|
||||
let event = match from_value::<NameEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomName(event))
|
||||
}
|
||||
EventType::RoomPowerLevels => {
|
||||
let event = match from_value::<PowerLevelsEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomPowerLevels(event))
|
||||
}
|
||||
EventType::RoomThirdPartyInvite => {
|
||||
let event = match from_value::<ThirdPartyInviteEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomThirdPartyInvite(event))
|
||||
}
|
||||
EventType::RoomTopic => {
|
||||
let event = match from_value::<TopicEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::RoomTopic(event))
|
||||
}
|
||||
EventType::Custom(_) => {
|
||||
let event = match from_value::<CustomStateEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(StateEvent::CustomState(event))
|
||||
}
|
||||
EventType::CallAnswer | EventType::CallCandidates | EventType::CallHangup |
|
||||
EventType::CallInvite | EventType::Presence | EventType::Receipt |
|
||||
EventType::RoomMessage | EventType::RoomRedaction | EventType::Tag |
|
||||
EventType::Typing => {
|
||||
return Err(D::Error::custom("not a state event".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_t_for_event {
|
||||
($ty:ty, $variant:ident) => {
|
||||
impl From<$ty> for Event {
|
||||
|
@ -1,8 +1,7 @@
|
||||
//! Enums for heterogeneous collections of events, exclusive to event types that implement "at
|
||||
//! most" the trait of the same name.
|
||||
|
||||
use CustomEvent;
|
||||
use CustomRoomEvent;
|
||||
use {CustomEvent, CustomRoomEvent, EventType};
|
||||
use call::answer::AnswerEvent;
|
||||
use call::candidates::CandidatesEvent;
|
||||
use call::hangup::HangupEvent;
|
||||
@ -14,6 +13,9 @@ use room::redaction::RedactionEvent;
|
||||
use tag::TagEvent;
|
||||
use typing::TypingEvent;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Error as SerdeError, Serialize, Serializer};
|
||||
use serde_json::{Value, from_value};
|
||||
|
||||
pub use super::all::StateEvent;
|
||||
|
||||
/// A basic event.
|
||||
@ -48,6 +50,181 @@ pub enum RoomEvent {
|
||||
CustomRoom(CustomRoomEvent),
|
||||
}
|
||||
|
||||
impl Serialize for Event {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
Event::Presence(ref event) => event.serialize(serializer),
|
||||
Event::Receipt(ref event) => event.serialize(serializer),
|
||||
Event::Tag(ref event) => event.serialize(serializer),
|
||||
Event::Typing(ref event) => event.serialize(serializer),
|
||||
Event::Custom(ref event) => event.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for Event {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
let value: Value = try!(Deserialize::deserialize(deserializer));
|
||||
|
||||
let event_type_value = match value.find("type") {
|
||||
Some(value) => value.clone(),
|
||||
None => return Err(D::Error::missing_field("type")),
|
||||
};
|
||||
|
||||
let event_type = match from_value::<EventType>(event_type_value.clone()) {
|
||||
Ok(event_type) => event_type,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
match event_type {
|
||||
EventType::Presence => {
|
||||
let event = match from_value::<PresenceEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Presence(event))
|
||||
}
|
||||
EventType::Receipt => {
|
||||
let event = match from_value::<ReceiptEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Receipt(event))
|
||||
}
|
||||
EventType::Tag => {
|
||||
let event = match from_value::<TagEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Tag(event))
|
||||
}
|
||||
EventType::Typing => {
|
||||
let event = match from_value::<TypingEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Typing(event))
|
||||
}
|
||||
EventType::Custom(_) => {
|
||||
let event = match from_value::<CustomEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(Event::Custom(event))
|
||||
}
|
||||
EventType::CallAnswer | EventType::CallCandidates | EventType::CallHangup |
|
||||
EventType::CallInvite | EventType::RoomAliases | EventType::RoomAvatar |
|
||||
EventType::RoomCanonicalAlias | EventType::RoomCreate | EventType::RoomGuestAccess |
|
||||
EventType::RoomHistoryVisibility | EventType::RoomJoinRules | EventType::RoomMember |
|
||||
EventType::RoomMessage | EventType::RoomName | EventType::RoomPowerLevels |
|
||||
EventType::RoomRedaction | EventType::RoomThirdPartyInvite | EventType::RoomTopic => {
|
||||
return Err(D::Error::custom("not exclusively a basic event".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for RoomEvent {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
RoomEvent::CallAnswer(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CallCandidates(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CallHangup(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CallInvite(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomMessage(ref event) => event.serialize(serializer),
|
||||
RoomEvent::RoomRedaction(ref event) => event.serialize(serializer),
|
||||
RoomEvent::CustomRoom(ref event) => event.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for RoomEvent {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
|
||||
let value: Value = try!(Deserialize::deserialize(deserializer));
|
||||
|
||||
let event_type_value = match value.find("type") {
|
||||
Some(value) => value.clone(),
|
||||
None => return Err(D::Error::missing_field("type")),
|
||||
};
|
||||
|
||||
let event_type = match from_value::<EventType>(event_type_value.clone()) {
|
||||
Ok(event_type) => event_type,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
match event_type {
|
||||
EventType::CallAnswer => {
|
||||
let event = match from_value::<AnswerEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallAnswer(event))
|
||||
}
|
||||
EventType::CallCandidates => {
|
||||
let event = match from_value::<CandidatesEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallCandidates(event))
|
||||
}
|
||||
EventType::CallHangup => {
|
||||
let event = match from_value::<HangupEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallHangup(event))
|
||||
}
|
||||
EventType::CallInvite => {
|
||||
let event = match from_value::<InviteEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CallInvite(event))
|
||||
}
|
||||
EventType::RoomMessage => {
|
||||
let event = match from_value::<MessageEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomMessage(event))
|
||||
}
|
||||
EventType::RoomRedaction => {
|
||||
let event = match from_value::<RedactionEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::RoomRedaction(event))
|
||||
}
|
||||
EventType::Custom(_) => {
|
||||
let event = match from_value::<CustomRoomEvent>(value) {
|
||||
Ok(event) => event,
|
||||
Err(error) => return Err(D::Error::custom(error.to_string())),
|
||||
};
|
||||
|
||||
Ok(RoomEvent::CustomRoom(event))
|
||||
}
|
||||
EventType::Presence | EventType::Receipt | EventType::RoomAliases |
|
||||
EventType::RoomAvatar | EventType::RoomCanonicalAlias | EventType::RoomCreate |
|
||||
EventType::RoomGuestAccess | EventType::RoomHistoryVisibility |
|
||||
EventType::RoomJoinRules | EventType::RoomMember | EventType::RoomName |
|
||||
EventType::RoomPowerLevels |EventType::RoomThirdPartyInvite | EventType::RoomTopic |
|
||||
EventType::Tag | EventType::Typing => {
|
||||
return Err(D::Error::custom("not exclusively a room event".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
macro_rules! impl_from_t_for_event {
|
||||
($ty:ty, $variant:ident) => {
|
||||
impl From<$ty> for Event {
|
||||
|
Loading…
x
Reference in New Issue
Block a user