use matrix_sdk_common::ROOM_VERSION_RULES_FALLBACK;
use ruma::{
OwnedUserId, RoomVersionId, assign,
events::{
EmptyStateKey, RedactContent, RedactedStateEventContent, StateEventType,
macros::EventContent,
room::create::{PreviousRoom, RoomCreateEventContent},
},
room::RoomType,
room_version_rules::RedactionRules,
};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[ruma_event(type = "m.room.create", kind = State, state_key_type = EmptyStateKey, custom_redacted)]
pub struct RoomCreateWithCreatorEventContent {
pub creator: OwnedUserId,
#[serde(
rename = "m.federate",
default = "ruma::serde::default_true",
skip_serializing_if = "ruma::serde::is_true"
)]
pub federate: bool,
#[serde(default = "default_create_room_version_id")]
pub room_version: RoomVersionId,
#[serde(skip_serializing_if = "Option::is_none")]
pub predecessor: Option<PreviousRoom>,
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
pub room_type: Option<RoomType>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub additional_creators: Vec<OwnedUserId>,
}
impl RoomCreateWithCreatorEventContent {
pub fn from_event_content(content: RoomCreateEventContent, sender: OwnedUserId) -> Self {
let RoomCreateEventContent {
federate,
room_version,
predecessor,
room_type,
additional_creators,
..
} = content;
Self {
creator: sender,
federate,
room_version,
predecessor,
room_type,
additional_creators,
}
}
fn into_event_content(self) -> (RoomCreateEventContent, OwnedUserId) {
let Self { creator, federate, room_version, predecessor, room_type, additional_creators } =
self;
#[allow(deprecated)]
let content = assign!(RoomCreateEventContent::new_v11(), {
creator: Some(creator.clone()),
federate,
room_version,
predecessor,
room_type,
additional_creators,
});
(content, creator)
}
pub(crate) fn creators(&self) -> Vec<OwnedUserId> {
let rules = self.room_version.rules().unwrap_or(ROOM_VERSION_RULES_FALLBACK);
if rules.authorization.explicitly_privilege_room_creators {
std::iter::once(self.creator.clone())
.chain(self.additional_creators.iter().cloned())
.collect()
} else {
vec![self.creator.clone()]
}
}
}
pub type RedactedRoomCreateWithCreatorEventContent = RoomCreateWithCreatorEventContent;
impl RedactedStateEventContent for RedactedRoomCreateWithCreatorEventContent {
type StateKey = EmptyStateKey;
fn event_type(&self) -> StateEventType {
StateEventType::RoomCreate
}
}
impl RedactContent for RoomCreateWithCreatorEventContent {
type Redacted = RedactedRoomCreateWithCreatorEventContent;
fn redact(self, rules: &RedactionRules) -> Self::Redacted {
let (content, sender) = self.into_event_content();
let content = content.redact(rules);
Self::from_event_content(content, sender)
}
}
fn default_create_room_version_id() -> RoomVersionId {
RoomVersionId::V1
}