From 3a62aaf4c759b35c04c663fd40f4d3c59e3bdd59 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Mon, 27 Nov 2017 17:08:51 +0200 Subject: [PATCH] Add m.room.pinned_events --- src/collections/all.rs | 37 +++++++++++++++++++++++ src/collections/only.rs | 6 ++-- src/lib.rs | 4 +++ src/room/mod.rs | 1 + src/room/pinned_events.rs | 63 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/room/pinned_events.rs diff --git a/src/collections/all.rs b/src/collections/all.rs index eaa9a3ef..a1a3b53f 100644 --- a/src/collections/all.rs +++ b/src/collections/all.rs @@ -19,6 +19,7 @@ use room::join_rules::JoinRulesEvent; use room::member::MemberEvent; use room::message::MessageEvent; use room::name::NameEvent; +use room::pinned_events::PinnedEventsEvent; use room::power_levels::PowerLevelsEvent; use room::redaction::RedactionEvent; use room::third_party_invite::ThirdPartyInviteEvent; @@ -67,6 +68,8 @@ pub enum Event { RoomMessage(MessageEvent), /// m.room.name RoomName(NameEvent), + /// m.room.pinned_events + RoomPinnedEvents(PinnedEventsEvent), /// m.room.power_levels RoomPowerLevels(PowerLevelsEvent), /// m.room.redaction @@ -118,6 +121,8 @@ pub enum RoomEvent { RoomMessage(MessageEvent), /// m.room.name RoomName(NameEvent), + /// m.room.pinned_events + RoomPinnedEvents(PinnedEventsEvent), /// m.room.power_levels RoomPowerLevels(PowerLevelsEvent), /// m.room.redaction @@ -153,6 +158,8 @@ pub enum StateEvent { RoomMember(MemberEvent), /// m.room.name RoomName(NameEvent), + /// m.room.pinned_events + RoomPinnedEvents(PinnedEventsEvent), /// m.room.power_levels RoomPowerLevels(PowerLevelsEvent), /// m.room.third_party_invite @@ -183,6 +190,7 @@ impl Serialize for Event { Event::RoomMember(ref event) => event.serialize(serializer), Event::RoomMessage(ref event) => event.serialize(serializer), Event::RoomName(ref event) => event.serialize(serializer), + Event::RoomPinnedEvents(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), @@ -347,6 +355,14 @@ impl<'de> Deserialize<'de> for Event { Ok(Event::RoomName(event)) } + EventType::RoomPinnedEvents => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(Event::RoomPinnedEvents(event)) + } EventType::RoomPowerLevels => { let event = match from_value::(value) { Ok(event) => event, @@ -441,6 +457,7 @@ impl Serialize for RoomEvent { RoomEvent::RoomMember(ref event) => event.serialize(serializer), RoomEvent::RoomMessage(ref event) => event.serialize(serializer), RoomEvent::RoomName(ref event) => event.serialize(serializer), + RoomEvent::RoomPinnedEvents(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), @@ -578,6 +595,14 @@ impl<'de> Deserialize<'de> for RoomEvent { Ok(RoomEvent::RoomName(event)) } + EventType::RoomPinnedEvents => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(RoomEvent::RoomPinnedEvents(event)) + } EventType::RoomPowerLevels => { let event = match from_value::(value) { Ok(event) => event, @@ -650,6 +675,7 @@ impl Serialize for StateEvent { StateEvent::RoomJoinRules(ref event) => event.serialize(serializer), StateEvent::RoomMember(ref event) => event.serialize(serializer), StateEvent::RoomName(ref event) => event.serialize(serializer), + StateEvent::RoomPinnedEvents(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), @@ -745,6 +771,14 @@ impl<'de> Deserialize<'de> for StateEvent { Ok(StateEvent::RoomName(event)) } + EventType::RoomPinnedEvents => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(StateEvent::RoomPinnedEvents(event)) + } EventType::RoomPowerLevels => { let event = match from_value::(value) { Ok(event) => event, @@ -821,6 +855,7 @@ impl_from_t_for_event!(JoinRulesEvent, RoomJoinRules); impl_from_t_for_event!(MemberEvent, RoomMember); impl_from_t_for_event!(MessageEvent, RoomMessage); impl_from_t_for_event!(NameEvent, RoomName); +impl_from_t_for_event!(PinnedEventsEvent, RoomPinnedEvents); impl_from_t_for_event!(PowerLevelsEvent, RoomPowerLevels); impl_from_t_for_event!(RedactionEvent, RoomRedaction); impl_from_t_for_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); @@ -855,6 +890,7 @@ impl_from_t_for_room_event!(JoinRulesEvent, RoomJoinRules); impl_from_t_for_room_event!(MemberEvent, RoomMember); impl_from_t_for_room_event!(MessageEvent, RoomMessage); impl_from_t_for_room_event!(NameEvent, RoomName); +impl_from_t_for_room_event!(PinnedEventsEvent, RoomPinnedEvents); impl_from_t_for_room_event!(PowerLevelsEvent, RoomPowerLevels); impl_from_t_for_room_event!(RedactionEvent, RoomRedaction); impl_from_t_for_room_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); @@ -881,6 +917,7 @@ impl_from_t_for_state_event!(HistoryVisibilityEvent, RoomHistoryVisibility); impl_from_t_for_state_event!(JoinRulesEvent, RoomJoinRules); impl_from_t_for_state_event!(MemberEvent, RoomMember); impl_from_t_for_state_event!(NameEvent, RoomName); +impl_from_t_for_state_event!(PinnedEventsEvent, RoomPinnedEvents); impl_from_t_for_state_event!(PowerLevelsEvent, RoomPowerLevels); impl_from_t_for_state_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); impl_from_t_for_state_event!(TopicEvent, RoomTopic); diff --git a/src/collections/only.rs b/src/collections/only.rs index 5d7b8ed7..9f0479df 100644 --- a/src/collections/only.rs +++ b/src/collections/only.rs @@ -136,8 +136,9 @@ impl<'de> Deserialize<'de> for Event { 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 => { + EventType::RoomMessage | EventType::RoomName | EventType::RoomPinnedEvents | + EventType::RoomPowerLevels | EventType::RoomRedaction | EventType::RoomThirdPartyInvite | + EventType::RoomTopic => { return Err(D::Error::custom("not exclusively a basic event".to_string())); } } @@ -241,6 +242,7 @@ impl<'de> Deserialize<'de> for RoomEvent { EventType::RoomJoinRules | EventType::RoomMember | EventType::RoomName | + EventType::RoomPinnedEvents | EventType::RoomPowerLevels | EventType::RoomThirdPartyInvite | EventType::RoomTopic | diff --git a/src/lib.rs b/src/lib.rs index aebcca34..d4f77f71 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -169,6 +169,8 @@ pub enum EventType { RoomMessage, /// m.room.name RoomName, + /// m.room.pinned_events + RoomPinnedEvents, /// m.room.power_levels RoomPowerLevels, /// m.room.redaction @@ -259,6 +261,7 @@ impl Display for EventType { EventType::RoomMember => "m.room.member", EventType::RoomMessage => "m.room.message", EventType::RoomName => "m.room.name", + EventType::RoomPinnedEvents=> "m.room.pinned_events", EventType::RoomPowerLevels => "m.room.power_levels", EventType::RoomRedaction => "m.room.redaction", EventType::RoomThirdPartyInvite => "m.room.third_party_invite", @@ -292,6 +295,7 @@ impl<'a> From<&'a str> for EventType { "m.room.member" => EventType::RoomMember, "m.room.message" => EventType::RoomMessage, "m.room.name" => EventType::RoomName, + "m.room.pinned_events" => EventType::RoomPinnedEvents, "m.room.power_levels" => EventType::RoomPowerLevels, "m.room.redaction" => EventType::RoomRedaction, "m.room.third_party_invite" => EventType::RoomThirdPartyInvite, diff --git a/src/room/mod.rs b/src/room/mod.rs index f54e6436..33283000 100644 --- a/src/room/mod.rs +++ b/src/room/mod.rs @@ -12,6 +12,7 @@ pub mod join_rules; pub mod member; pub mod message; pub mod name; +pub mod pinned_events; pub mod power_levels; pub mod redaction; pub mod third_party_invite; diff --git a/src/room/pinned_events.rs b/src/room/pinned_events.rs new file mode 100644 index 00000000..a96eb40d --- /dev/null +++ b/src/room/pinned_events.rs @@ -0,0 +1,63 @@ +//! Types for the *m.room.pinned_events* event. + +use ruma_identifiers::EventId; + +state_event! { + /// Used to "pin" particular events in a room for other participants to review later. + pub struct PinnedEventsEvent(PinnedEventsContent) {} +} + +/// The payload of a `NameEvent`. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct PinnedEventsContent { + /// An ordered list of event IDs to pin. + pub pinned: Vec, +} + +#[cfg(test)] +mod tests { + use ruma_identifiers::{EventId, RoomId, UserId}; + use serde_json::{from_str, to_string}; + + use Event; + use EventType; + use RoomEvent; + use StateEvent; + use room::pinned_events::{PinnedEventsEvent, PinnedEventsContent}; + + #[test] + fn serialization_deserialization() { + let mut content: PinnedEventsContent = PinnedEventsContent { + pinned: Vec::new() + }; + + content.pinned.push(EventId::new("example.com").unwrap()); + content.pinned.push(EventId::new("example.com").unwrap()); + + let event = PinnedEventsEvent { + content: content.clone(), + event_id: EventId::new("example.com").unwrap(), + event_type: EventType::RoomPinnedEvents, + origin_server_ts: 1432804485886, + prev_content: None, + room_id: RoomId::new("example.com").unwrap(), + sender: UserId::new("example.com").unwrap(), + state_key: "".to_string(), + unsigned: None, + }; + + let serialized_event = to_string(&event).unwrap(); + let parsed_event: PinnedEventsEvent = from_str(&serialized_event).unwrap(); + + assert_eq!(parsed_event.event_id(), event.event_id()); + assert_eq!(parsed_event.room_id(), event.room_id()); + assert_eq!(parsed_event.sender(), event.sender()); + assert_eq!(parsed_event.unsigned(), event.unsigned()); + assert_eq!(parsed_event.state_key(), event.state_key()); + assert_eq!(parsed_event.origin_server_ts(), event.origin_server_ts()); + + assert_eq!(parsed_event.content().pinned, event.content.pinned); + assert_eq!(parsed_event.content().pinned[0], content.pinned[0]); + assert_eq!(parsed_event.content().pinned[1], content.pinned[1]); + } +}