ruma_events/
image_pack.rs

1//! Types for image packs in Matrix ([MSC2545]).
2//!
3//! [MSC2545]: https://github.com/matrix-org/matrix-spec-proposals/pull/2545
4
5use std::collections::{BTreeMap, BTreeSet};
6
7use ruma_common::{serde::StringEnum, OwnedMxcUri, OwnedRoomId};
8use ruma_macros::EventContent;
9use serde::{Deserialize, Serialize};
10
11use crate::{room::ImageInfo, PrivOwnedStr};
12
13/// The content of an `im.ponies.room_emotes` event,
14/// the unstable version of `m.image_pack` in room state events.
15///
16/// State key is the identifier for the image pack in [ImagePackRoomsEventContent].
17#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
18#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
19#[ruma_event(type = "im.ponies.room_emotes", kind = State, state_key_type = String)]
20pub struct RoomImagePackEventContent {
21    /// A list of images available in this image pack.
22    ///
23    /// Keys in the map are shortcodes for the images.
24    pub images: BTreeMap<String, PackImage>,
25
26    /// Image pack info.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub pack: Option<PackInfo>,
29}
30
31impl RoomImagePackEventContent {
32    /// Creates a new `RoomImagePackEventContent` with a list of images.
33    pub fn new(images: BTreeMap<String, PackImage>) -> Self {
34        Self { images, pack: None }
35    }
36}
37
38/// The content of an `im.ponies.user_emotes` event,
39/// the unstable version of `m.image_pack` in account data events.
40#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
41#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
42#[ruma_event(type = "im.ponies.user_emotes", kind = GlobalAccountData)]
43pub struct AccountImagePackEventContent {
44    /// A list of images available in this image pack.
45    ///
46    /// Keys in the map are shortcodes for the images.
47    pub images: BTreeMap<String, PackImage>,
48
49    /// Image pack info.
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub pack: Option<PackInfo>,
52}
53
54impl AccountImagePackEventContent {
55    /// Creates a new `AccountImagePackEventContent` with a list of images.
56    pub fn new(images: BTreeMap<String, PackImage>) -> Self {
57        Self { images, pack: None }
58    }
59}
60
61/// An image object in a image pack.
62#[derive(Clone, Debug, Deserialize, Serialize)]
63#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
64pub struct PackImage {
65    /// The MXC URI to the media file.
66    pub url: OwnedMxcUri,
67
68    /// An optional text body for this image.
69    /// Useful for the sticker body text or the emote alt text.
70    ///
71    /// Defaults to the shortcode.
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub body: Option<String>,
74
75    /// The [ImageInfo] object used for the `info` block of `m.sticker` events.
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub info: Option<ImageInfo>,
78
79    /// The usages for the image.
80    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
81    pub usage: BTreeSet<PackUsage>,
82}
83
84impl PackImage {
85    /// Creates a new `PackImage` with the given MXC URI to the media file.
86    pub fn new(url: OwnedMxcUri) -> Self {
87        Self { url, body: None, info: None, usage: BTreeSet::new() }
88    }
89}
90
91/// A description for the pack.
92#[derive(Clone, Debug, Default, Deserialize, Serialize)]
93#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
94pub struct PackInfo {
95    /// A display name for the pack.
96    /// This does not have to be unique from other packs in a room.
97    ///
98    /// Defaults to the room name, if the image pack event is in the room.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub display_name: Option<String>,
101
102    /// The MXC URI of an avatar/icon to display for the pack.
103    ///
104    /// Defaults to the room avatar, if the pack is in the room.
105    /// Otherwise, the pack does not have an avatar.
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub avatar_url: Option<OwnedMxcUri>,
108
109    /// The usages for the pack.
110    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
111    pub usage: BTreeSet<PackUsage>,
112
113    /// The attribution of this pack.
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub attribution: Option<String>,
116}
117
118impl PackInfo {
119    /// Creates a new empty `PackInfo`.
120    pub fn new() -> Self {
121        Self::default()
122    }
123}
124
125/// Usages for either an image pack or an individual image.
126#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
127#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
128#[ruma_enum(rename_all = "snake_case")]
129#[non_exhaustive]
130pub enum PackUsage {
131    /// Pack or image is usable as a emoticon.
132    Emoticon,
133
134    /// Pack or image is usable as a sticker.
135    Sticker,
136
137    #[doc(hidden)]
138    _Custom(PrivOwnedStr),
139}
140
141/// The content of an `im.ponies.emote_rooms` event,
142/// the unstable version of `m.image_pack.rooms`.
143#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
144#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
145#[ruma_event(type = "im.ponies.emote_rooms", kind = GlobalAccountData)]
146pub struct ImagePackRoomsEventContent {
147    /// A map of enabled image packs in each room.
148    pub rooms: BTreeMap<OwnedRoomId, BTreeMap<String, ImagePackRoomContent>>,
149}
150
151impl ImagePackRoomsEventContent {
152    /// Creates a new `ImagePackRoomsEventContent`
153    /// with a map of enabled image packs in each room.
154    pub fn new(rooms: BTreeMap<OwnedRoomId, BTreeMap<String, ImagePackRoomContent>>) -> Self {
155        Self { rooms }
156    }
157}
158
159/// Additional metadatas for a enabled room image pack.
160#[derive(Clone, Debug, Default, Deserialize, Serialize)]
161#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
162pub struct ImagePackRoomContent {}
163
164impl ImagePackRoomContent {
165    /// Creates a new empty `ImagePackRoomContent`.
166    pub fn new() -> Self {
167        Self {}
168    }
169}