1
0
Fork 0
ruma/crates/ruma-events/src/do_not_disturb.rs
2026-01-29 09:04:26 +01:00

169 lines
5.2 KiB
Rust

//! Types for the [`dm.filament.do_not_disturb`] event.
//!
//! [`dm.filament.do_not_disturb`]: https://github.com/matrix-org/matrix-spec-proposals/pull/4359
use std::collections::BTreeMap;
use ruma_common::OwnedRoomId;
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
/// The content of a `dm.filament.do_not_disturb` event.
///
/// A list of rooms in "Do not Disturb" mode.
#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
#[ruma_event(type = "dm.filament.do_not_disturb", kind = GlobalAccountData)]
pub struct DoNotDisturbEventContent {
/// A map of rooms in which to inhibit notifications.
///
/// As [`DoNotDisturbRoom`] is currently empty, only the room IDs are useful and
/// can be accessed with the `.keys()` and `into_keys()` iterators.
pub rooms: BTreeMap<DoNotDisturbRoomKey, DoNotDisturbRoom>,
}
impl DoNotDisturbEventContent {
/// Creates a new `DoNotDisturbEventContent` from the given map of [`DoNotDisturbRoom`]s.
pub fn new(rooms: BTreeMap<DoNotDisturbRoomKey, DoNotDisturbRoom>) -> Self {
Self { rooms }
}
}
impl FromIterator<DoNotDisturbRoomKey> for DoNotDisturbEventContent {
fn from_iter<T: IntoIterator<Item = DoNotDisturbRoomKey>>(iter: T) -> Self {
Self::new(iter.into_iter().map(|key| (key, DoNotDisturbRoom {})).collect())
}
}
impl FromIterator<OwnedRoomId> for DoNotDisturbEventContent {
fn from_iter<T: IntoIterator<Item = OwnedRoomId>>(iter: T) -> Self {
iter.into_iter().map(DoNotDisturbRoomKey::SingleRoom).collect()
}
}
impl Extend<DoNotDisturbRoomKey> for DoNotDisturbEventContent {
fn extend<T: IntoIterator<Item = DoNotDisturbRoomKey>>(&mut self, iter: T) {
self.rooms.extend(iter.into_iter().map(|key| (key, DoNotDisturbRoom {})));
}
}
impl Extend<OwnedRoomId> for DoNotDisturbEventContent {
fn extend<T: IntoIterator<Item = OwnedRoomId>>(&mut self, iter: T) {
self.extend(iter.into_iter().map(DoNotDisturbRoomKey::SingleRoom));
}
}
/// The key for a "Do not Disturb" setting.
///
/// This either matches a single room or all rooms.
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
pub enum DoNotDisturbRoomKey {
/// Match any room.
#[serde(rename = "*")]
AllRooms,
/// Match a single room based on its room ID.
#[serde(untagged)]
SingleRoom(OwnedRoomId),
}
/// Details about a room in "Do not Disturb" mode.
///
/// This is currently empty.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
pub struct DoNotDisturbRoom {}
impl DoNotDisturbRoom {
/// Creates an empty `DoNotDisturbRoom`.
pub fn new() -> Self {
Self::default()
}
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use assert_matches2::assert_matches;
use ruma_common::{canonical_json::assert_to_canonical_json_eq, owned_room_id};
use serde_json::{from_value as from_json_value, json};
use super::DoNotDisturbEventContent;
use crate::{AnyGlobalAccountDataEvent, do_not_disturb::DoNotDisturbRoomKey};
#[test]
fn serialization_with_single_room() {
let do_not_disturb_room_list: DoNotDisturbEventContent =
vec![owned_room_id!("!foo:bar.baz")].into_iter().collect();
assert_to_canonical_json_eq!(
do_not_disturb_room_list,
json!({
"rooms": {
"!foo:bar.baz": {}
},
}),
);
}
#[test]
fn serialization_with_all_rooms() {
let do_not_disturb_room_list = DoNotDisturbEventContent::new(BTreeMap::from([(
DoNotDisturbRoomKey::AllRooms,
Default::default(),
)]));
assert_to_canonical_json_eq!(
do_not_disturb_room_list,
json!({
"rooms": {
"*": {}
},
}),
);
}
#[test]
fn deserialization_with_single_room() {
let json = json!({
"content": {
"rooms": {
"!foo:bar.baz": {}
}
},
"type": "dm.filament.do_not_disturb"
});
assert_matches!(
from_json_value::<AnyGlobalAccountDataEvent>(json),
Ok(AnyGlobalAccountDataEvent::DoNotDisturb(ev))
);
assert_eq!(
ev.content.rooms.keys().collect::<Vec<_>>(),
vec![&DoNotDisturbRoomKey::SingleRoom(owned_room_id!("!foo:bar.baz"))]
);
}
#[test]
fn deserialization_with_all_room() {
let json = json!({
"content": {
"rooms": {
"*": {}
}
},
"type": "dm.filament.do_not_disturb"
});
assert_matches!(
from_json_value::<AnyGlobalAccountDataEvent>(json),
Ok(AnyGlobalAccountDataEvent::DoNotDisturb(ev))
);
assert_eq!(
ev.content.rooms.keys().collect::<Vec<_>>(),
vec![&DoNotDisturbRoomKey::AllRooms]
);
}
}