diff --git a/src/collections/all.rs b/src/collections/all.rs index 26d8918c..62400f48 100644 --- a/src/collections/all.rs +++ b/src/collections/all.rs @@ -27,6 +27,7 @@ use crate::{ third_party_invite::ThirdPartyInviteEvent, topic::TopicEvent, }, + sticker::StickerEvent, tag::TagEvent, typing::TypingEvent, CustomEvent, CustomRoomEvent, CustomStateEvent, EventType, @@ -89,6 +90,8 @@ pub enum Event { RoomThirdPartyInvite(ThirdPartyInviteEvent), /// m.room.topic RoomTopic(TopicEvent), + /// m.sticker + Sticker(StickerEvent), /// m.tag Tag(TagEvent), /// m.typing @@ -145,6 +148,8 @@ pub enum RoomEvent { RoomThirdPartyInvite(ThirdPartyInviteEvent), /// m.room.topic RoomTopic(TopicEvent), + /// m.sticker + Sticker(StickerEvent), /// Any room event that is not part of the specification. CustomRoom(CustomRoomEvent), /// Any state event that is not part of the specification. @@ -216,6 +221,7 @@ impl Serialize for Event { Event::RoomRedaction(ref event) => event.serialize(serializer), Event::RoomThirdPartyInvite(ref event) => event.serialize(serializer), Event::RoomTopic(ref event) => event.serialize(serializer), + Event::Sticker(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), @@ -443,6 +449,14 @@ impl<'de> Deserialize<'de> for Event { Ok(Event::RoomTopic(event)) } + EventType::Sticker => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(Event::Sticker(event)) + } EventType::Tag => { let event = match from_value::(value) { Ok(event) => event, @@ -516,6 +530,7 @@ impl Serialize for RoomEvent { RoomEvent::RoomRedaction(ref event) => event.serialize(serializer), RoomEvent::RoomThirdPartyInvite(ref event) => event.serialize(serializer), RoomEvent::RoomTopic(ref event) => event.serialize(serializer), + RoomEvent::Sticker(ref event) => event.serialize(serializer), RoomEvent::CustomRoom(ref event) => event.serialize(serializer), RoomEvent::CustomState(ref event) => event.serialize(serializer), } @@ -700,6 +715,14 @@ impl<'de> Deserialize<'de> for RoomEvent { Ok(RoomEvent::RoomTopic(event)) } + EventType::Sticker => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(RoomEvent::Sticker(event)) + } EventType::Custom(_) => { if value.get("state_key").is_some() { let event = match from_value::(value) { @@ -894,6 +917,7 @@ impl<'de> Deserialize<'de> for StateEvent { | EventType::RoomMessage | EventType::RoomMessageFeedback | EventType::RoomRedaction + | EventType::Sticker | EventType::Tag | EventType::Typing => Err(D::Error::custom("not a state event".to_string())), } @@ -935,6 +959,7 @@ impl_from_t_for_event!(PowerLevelsEvent, RoomPowerLevels); impl_from_t_for_event!(RedactionEvent, RoomRedaction); impl_from_t_for_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); impl_from_t_for_event!(TopicEvent, RoomTopic); +impl_from_t_for_event!(StickerEvent, Sticker); impl_from_t_for_event!(TagEvent, Tag); impl_from_t_for_event!(TypingEvent, Typing); impl_from_t_for_event!(CustomEvent, Custom); @@ -969,6 +994,7 @@ 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!(StickerEvent, Sticker); impl_from_t_for_room_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); impl_from_t_for_room_event!(TopicEvent, RoomTopic); impl_from_t_for_room_event!(CustomRoomEvent, CustomRoom); diff --git a/src/collections/only.rs b/src/collections/only.rs index 62805365..853213a4 100644 --- a/src/collections/only.rs +++ b/src/collections/only.rs @@ -18,6 +18,7 @@ use crate::{ message::{feedback::FeedbackEvent, MessageEvent}, redaction::RedactionEvent, }, + sticker::StickerEvent, tag::TagEvent, typing::TypingEvent, CustomEvent, CustomRoomEvent, EventType, @@ -62,6 +63,8 @@ pub enum RoomEvent { RoomMessageFeedback(FeedbackEvent), /// m.room.redaction RoomRedaction(RedactionEvent), + /// m.sticker + Sticker(StickerEvent), /// Any room event that is not part of the specification. CustomRoom(CustomRoomEvent), } @@ -185,7 +188,8 @@ impl<'de> Deserialize<'de> for Event { | EventType::RoomPowerLevels | EventType::RoomRedaction | EventType::RoomThirdPartyInvite - | EventType::RoomTopic => Err(D::Error::custom( + | EventType::RoomTopic + | EventType::Sticker => Err(D::Error::custom( "not exclusively a basic event".to_string(), )), } @@ -205,6 +209,7 @@ impl Serialize for RoomEvent { RoomEvent::RoomMessage(ref event) => event.serialize(serializer), RoomEvent::RoomMessageFeedback(ref event) => event.serialize(serializer), RoomEvent::RoomRedaction(ref event) => event.serialize(serializer), + RoomEvent::Sticker(ref event) => event.serialize(serializer), RoomEvent::CustomRoom(ref event) => event.serialize(serializer), } } @@ -284,6 +289,14 @@ impl<'de> Deserialize<'de> for RoomEvent { Ok(RoomEvent::RoomRedaction(event)) } + EventType::Sticker => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(RoomEvent::Sticker(event)) + } EventType::Custom(_) => { let event = match from_value::(value) { Ok(event) => event, @@ -353,4 +366,5 @@ impl_from_t_for_room_event!(InviteEvent, CallInvite); impl_from_t_for_room_event!(MessageEvent, RoomMessage); impl_from_t_for_room_event!(FeedbackEvent, RoomMessageFeedback); impl_from_t_for_room_event!(RedactionEvent, RoomRedaction); +impl_from_t_for_room_event!(StickerEvent, Sticker); impl_from_t_for_room_event!(CustomRoomEvent, CustomRoom); diff --git a/src/lib.rs b/src/lib.rs index fc6c44e0..49da7ced 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -123,6 +123,7 @@ pub mod ignored_user_list; pub mod presence; pub mod receipt; pub mod room; +pub mod sticker; pub mod stripped; pub mod tag; pub mod typing; @@ -184,6 +185,8 @@ pub enum EventType { RoomThirdPartyInvite, /// m.room.topic RoomTopic, + /// m.sticker + Sticker, /// m.tag Tag, /// m.typing @@ -281,6 +284,7 @@ impl Display for EventType { EventType::RoomRedaction => "m.room.redaction", EventType::RoomThirdPartyInvite => "m.room.third_party_invite", EventType::RoomTopic => "m.room.topic", + EventType::Sticker => "m.sticker", EventType::Tag => "m.tag", EventType::Typing => "m.typing", EventType::Custom(ref event_type) => event_type, @@ -318,6 +322,7 @@ impl<'a> From<&'a str> for EventType { "m.room.redaction" => EventType::RoomRedaction, "m.room.third_party_invite" => EventType::RoomThirdPartyInvite, "m.room.topic" => EventType::RoomTopic, + "m.sticker" => EventType::Sticker, "m.tag" => EventType::Tag, "m.typing" => EventType::Typing, event_type => EventType::Custom(event_type.to_string()), diff --git a/src/sticker.rs b/src/sticker.rs new file mode 100644 index 00000000..b63694c3 --- /dev/null +++ b/src/sticker.rs @@ -0,0 +1,22 @@ +//! Types for the *m.sticker* event. + +use serde::{Deserialize, Serialize}; + +use crate::room::ImageInfo; + +room_event! { + /// A sticker message. + pub struct StickerEvent(StickerEventContent) {} +} + +/// The payload of a `StickerEvent`. +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct StickerEventContent { + /// A textual representation or associated description of the sticker image. This could be the + /// alt text of the original image, or a message to accompany and further describe the sticker. + pub body: String, + /// Metadata about the image referred to in `url` including a thumbnail representation. + pub info: ImageInfo, + /// The URL to the sticker image. This must be a valid `mxc://` URI. + pub url: String, +}