ruma_common/
room_version_rules.rs

1//! Types for the rules applied to the different [room versions].
2//!
3//! [room versions]: https://spec.matrix.org/latest/rooms/
4
5#[allow(clippy::disallowed_types)]
6use std::collections::HashSet;
7
8use as_variant::as_variant;
9
10use crate::OwnedUserId;
11
12/// The rules applied to a [room version].
13///
14/// This type can be constructed from one of its constants (like [`RoomVersionRules::V1`]), or from
15/// [`RoomVersionId::rules()`].
16///
17/// [room version]: https://spec.matrix.org/latest/rooms/
18/// [`RoomVersionId::rules()`]: crate::RoomVersionId::rules
19#[derive(Debug, Clone)]
20#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
21pub struct RoomVersionRules {
22    /// The stability of the room version.
23    pub disposition: RoomVersionDisposition,
24
25    /// The format of event IDs.
26    pub event_id_format: EventIdFormatVersion,
27
28    /// The format of room IDs.
29    pub room_id_format: RoomIdFormatVersion,
30
31    /// The state resolution algorithm used.
32    pub state_res: StateResolutionVersion,
33
34    /// Whether to enforce the key validity period when verifying signatures ([spec]), introduced
35    /// in room version 5.
36    ///
37    /// [spec]: https://spec.matrix.org/latest/rooms/v5/#signing-key-validity-period
38    pub enforce_key_validity: bool,
39
40    /// The tweaks in the authorization rules.
41    pub authorization: AuthorizationRules,
42
43    /// The tweaks in the redaction algorithm.
44    pub redaction: RedactionRules,
45
46    /// The tweaks for verifying signatures.
47    pub signatures: SignaturesRules,
48
49    /// The tweaks for verifying the event format.
50    pub event_format: EventFormatRules,
51}
52
53impl RoomVersionRules {
54    /// Rules for [room version 1].
55    ///
56    /// [room version 1]: https://spec.matrix.org/latest/rooms/v1/
57    pub const V1: Self = Self {
58        disposition: RoomVersionDisposition::Stable,
59        event_id_format: EventIdFormatVersion::V1,
60        room_id_format: RoomIdFormatVersion::V1,
61        state_res: StateResolutionVersion::V1,
62        enforce_key_validity: false,
63        authorization: AuthorizationRules::V1,
64        redaction: RedactionRules::V1,
65        signatures: SignaturesRules::V1,
66        event_format: EventFormatRules::V1,
67    };
68
69    /// Rules for [room version 2].
70    ///
71    /// [room version 2]: https://spec.matrix.org/latest/rooms/v2/
72    pub const V2: Self =
73        Self { state_res: StateResolutionVersion::V2(StateResolutionV2Rules::V2_0), ..Self::V1 };
74
75    /// Rules for [room version 3].
76    ///
77    /// [room version 3]: https://spec.matrix.org/latest/rooms/v3/
78    pub const V3: Self = Self {
79        event_id_format: EventIdFormatVersion::V2,
80        authorization: AuthorizationRules::V3,
81        signatures: SignaturesRules::V3,
82        event_format: EventFormatRules::V3,
83        ..Self::V2
84    };
85
86    /// Rules for [room version 4].
87    ///
88    /// [room version 4]: https://spec.matrix.org/latest/rooms/v4/
89    pub const V4: Self = Self { event_id_format: EventIdFormatVersion::V3, ..Self::V3 };
90
91    /// Rules for [room version 5].
92    ///
93    /// [room version 5]: https://spec.matrix.org/latest/rooms/v5/
94    pub const V5: Self = Self { enforce_key_validity: true, ..Self::V4 };
95
96    /// Rules for [room version 6].
97    ///
98    /// [room version 6]: https://spec.matrix.org/latest/rooms/v6/
99    pub const V6: Self =
100        Self { authorization: AuthorizationRules::V6, redaction: RedactionRules::V6, ..Self::V5 };
101
102    /// Rules for [room version 7].
103    ///
104    /// [room version 7]: https://spec.matrix.org/latest/rooms/v7/
105    pub const V7: Self = Self { authorization: AuthorizationRules::V7, ..Self::V6 };
106
107    /// Rules for [room version 8].
108    ///
109    /// [room version 8]: https://spec.matrix.org/latest/rooms/v8/
110    pub const V8: Self = Self {
111        authorization: AuthorizationRules::V8,
112        redaction: RedactionRules::V8,
113        signatures: SignaturesRules::V8,
114        ..Self::V7
115    };
116
117    /// Rules for [room version 9].
118    ///
119    /// [room version 9]: https://spec.matrix.org/latest/rooms/v9/
120    pub const V9: Self = Self { redaction: RedactionRules::V9, ..Self::V8 };
121
122    /// Rules for [room version 10].
123    ///
124    /// [room version 10]: https://spec.matrix.org/latest/rooms/v10/
125    pub const V10: Self = Self { authorization: AuthorizationRules::V10, ..Self::V9 };
126
127    /// Rules for [room version 11].
128    ///
129    /// [room version 11]: https://spec.matrix.org/latest/rooms/v11/
130    pub const V11: Self = Self {
131        authorization: AuthorizationRules::V11,
132        redaction: RedactionRules::V11,
133        ..Self::V10
134    };
135
136    /// Rules for room version `org.matrix.hydra.11`.
137    #[cfg(feature = "unstable-hydra")]
138    pub const HYDRA_V11: Self = Self { disposition: RoomVersionDisposition::Unstable, ..Self::V12 };
139
140    /// Rules for room version 12.
141    pub const V12: Self = Self {
142        room_id_format: RoomIdFormatVersion::V2,
143        authorization: AuthorizationRules::V12,
144        event_format: EventFormatRules::V12,
145        state_res: StateResolutionVersion::V2(StateResolutionV2Rules::V2_1),
146        ..Self::V11
147    };
148
149    /// Rules for room version `org.matrix.msc2870` ([MSC2870]).
150    ///
151    /// [MSC2870]: https://github.com/matrix-org/matrix-spec-proposals/pull/2870
152    #[cfg(feature = "unstable-msc2870")]
153    pub const MSC2870: Self = Self {
154        disposition: RoomVersionDisposition::Unstable,
155        redaction: RedactionRules::MSC2870,
156        ..Self::V11
157    };
158}
159
160/// The stability of a room version.
161#[derive(Debug, Clone, Copy, PartialEq, Eq)]
162#[allow(clippy::exhaustive_enums)]
163pub enum RoomVersionDisposition {
164    /// A room version that has a stable specification.
165    Stable,
166
167    /// A room version that is not yet fully specified.
168    Unstable,
169}
170
171/// The format of [event IDs] for a room version.
172///
173/// [event IDs]: https://spec.matrix.org/latest/appendices/#event-ids
174#[derive(Debug, Clone, Copy, PartialEq, Eq)]
175#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
176pub enum EventIdFormatVersion {
177    /// `$id:server` format ([spec]), introduced in room version 1.
178    ///
179    /// [spec]: https://spec.matrix.org/latest/rooms/v1/#event-ids
180    V1,
181
182    /// `$hash` format using standard unpadded base64 ([spec]), introduced in room version 3.
183    ///
184    /// [spec]: https://spec.matrix.org/latest/rooms/v3/#event-ids
185    V2,
186
187    /// `$hash` format using URL-safe unpadded base64 ([spec]), introduced in room version 4.
188    ///
189    /// [spec]: https://spec.matrix.org/latest/rooms/v4/#event-ids
190    V3,
191}
192
193/// The format of [room IDs] for a room version.
194///
195/// [room IDs]: https://spec.matrix.org/latest/appendices/#room-ids
196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
197#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
198pub enum RoomIdFormatVersion {
199    /// `!id:server` format, introduced in room version 1.
200    V1,
201
202    /// `!hash` format using the reference hash of the `m.room.create` event of the room,
203    /// introduced in room version 12.
204    V2,
205}
206
207/// The version of [state resolution] for a room version.
208///
209/// [state resolution]: https://spec.matrix.org/latest/server-server-api/#room-state-resolution
210#[derive(Debug, Clone, Copy, PartialEq, Eq)]
211#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
212pub enum StateResolutionVersion {
213    /// First version of the state resolution algorithm ([spec]), introduced in room version 1.
214    ///
215    /// [spec]: https://spec.matrix.org/latest/rooms/v1/#state-resolution
216    V1,
217
218    /// Second version of the state resolution algorithm ([spec]), introduced in room version 2.
219    ///
220    /// [spec]: https://spec.matrix.org/latest/rooms/v2/#state-resolution
221    V2(StateResolutionV2Rules),
222}
223
224impl StateResolutionVersion {
225    /// Gets the `StateResolutionV2Rules` for the room version, if it uses the second version of
226    /// the state resolution algorithm.
227    pub fn v2_rules(&self) -> Option<&StateResolutionV2Rules> {
228        as_variant!(self, StateResolutionVersion::V2)
229    }
230}
231
232/// The tweaks in the [state resolution v2 algorithm] for a room version.
233///
234/// This type can be constructed from one of its constants (like [`StateResolutionV2Rules::V2_0`]),
235/// or by constructing a [`RoomVersionRules`] first and using the `state_res` field (if the room
236/// version uses version 2 of the state resolution algorithm).
237///
238/// [state resolution v2 algorithm]: https://spec.matrix.org/latest/rooms/v2/#state-resolution
239#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241pub struct StateResolutionV2Rules {
242    /// Whether to begin the first phase of iterative auth checks with an empty state map, as
243    /// opposed to one containing the unconflicted state, enabled since room version 12.
244    pub begin_iterative_auth_checks_with_empty_state_map: bool,
245
246    /// Whether to include the conflicted state subgraph in the full conflicted state, enabled
247    /// since room version 12.
248    pub consider_conflicted_state_subgraph: bool,
249}
250
251impl StateResolutionV2Rules {
252    /// The first version of the second iteration of the state resolution algorithm, introduced in
253    /// room version 2.
254    pub const V2_0: Self = Self {
255        begin_iterative_auth_checks_with_empty_state_map: false,
256        consider_conflicted_state_subgraph: false,
257    };
258
259    /// The second version of the second iteration of the state resolution algorithm, introduced in
260    /// room version 12.
261    pub const V2_1: Self = Self {
262        begin_iterative_auth_checks_with_empty_state_map: true,
263        consider_conflicted_state_subgraph: true,
264        ..Self::V2_0
265    };
266}
267
268/// The tweaks in the [authorization rules] for a room version.
269///
270/// This type can be constructed from one of its constants (like [`AuthorizationRules::V1`]), or by
271/// constructing a [`RoomVersionRules`] first and using the `authorization` field.
272///
273/// [authorization rules]: https://spec.matrix.org/latest/server-server-api/#authorization-rules
274#[derive(Debug, Clone)]
275#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
276pub struct AuthorizationRules {
277    /// Whether to apply special authorization rules for `m.room.redaction` events ([spec]),
278    /// disabled since room version 3.
279    ///
280    /// [spec]: https://spec.matrix.org/latest/rooms/v3/#handling-redactions
281    pub special_case_room_redaction: bool,
282
283    /// Whether to apply special authorization rules for `m.room.aliases` events ([spec]), disabled
284    /// since room version 6.
285    ///
286    /// [spec]: https://spec.matrix.org/latest/rooms/v6/#authorization-rules
287    pub special_case_room_aliases: bool,
288
289    /// Whether to strictly enforce [canonical JSON] ([spec]), introduced in room version 6.
290    ///
291    /// Numbers in Canonical JSON must be integers in the range [-2<sup>53</sup> + 1,
292    /// 2<sup>53</sup> - 1], represented without exponents or decimal places, and negative zero
293    /// (`-0`) MUST NOT appear.
294    ///
295    /// [canonical JSON]: https://spec.matrix.org/latest/appendices/#canonical-json
296    /// [spec]: https://spec.matrix.org/latest/rooms/v6/#canonical-json
297    pub strict_canonical_json: bool,
298
299    /// Whether to check the `notifications` field when checking `m.room.power_levels` events
300    /// ([spec]), introduced in room version 6.
301    ///
302    /// [spec]: https://spec.matrix.org/latest/rooms/v6/#authorization-rules
303    pub limit_notifications_power_levels: bool,
304
305    /// Whether to allow the `knock` membership for `m.room.member` events and the `knock` join
306    /// rule for `m.room.join_rules` events ([spec]), introduced in room version 7.
307    ///
308    /// [spec]: https://spec.matrix.org/latest/rooms/v7/#authorization-rules
309    pub knocking: bool,
310
311    /// Whether to allow the `restricted` join rule for `m.room.join_rules` events ([spec]),
312    /// introduced in room version 8.
313    ///
314    /// [spec]: https://spec.matrix.org/latest/rooms/v8/#authorization-rules
315    pub restricted_join_rule: bool,
316
317    /// Whether to allow the `knock_restricted` join rule for `m.room.join_rules` events ([spec]),
318    /// introduced in room version 10.
319    ///
320    /// [spec]: https://spec.matrix.org/latest/rooms/v10/#authorization-rules
321    pub knock_restricted_join_rule: bool,
322
323    /// Whether to enforce that power levels values in `m.room.power_levels` events be integers
324    /// ([spec]), introduced in room version 10.
325    ///
326    /// [spec]: https://spec.matrix.org/latest/rooms/v10/#values-in-mroompower_levels-events-must-be-integers
327    pub integer_power_levels: bool,
328
329    /// Whether the room creator should be determined using the `m.room.create` event's `sender`,
330    /// instead of the event content's `creator` field ([spec]), introduced in room version 11.
331    ///
332    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#event-format
333    pub use_room_create_sender: bool,
334
335    /// Whether room creators should always be considered to have "infinite" power level,
336    /// introduced in room version 12.
337    pub explicitly_privilege_room_creators: bool,
338
339    /// Whether additional room creators can be set with the `content.additional_creators` field of
340    /// an `m.room.create` event, introduced in room version 12.
341    pub additional_room_creators: bool,
342
343    /// Whether to use the event ID of the `m.room.create` event of the room as the room ID,
344    /// introduced in room version 12.
345    pub room_create_event_id_as_room_id: bool,
346}
347
348impl AuthorizationRules {
349    /// Authorization rules as introduced in room version 1 ([spec]).
350    ///
351    /// [spec]: https://spec.matrix.org/latest/rooms/v1/#authorization-rules
352    pub const V1: Self = Self {
353        special_case_room_redaction: true,
354        special_case_room_aliases: true,
355        strict_canonical_json: false,
356        limit_notifications_power_levels: false,
357        knocking: false,
358        restricted_join_rule: false,
359        knock_restricted_join_rule: false,
360        integer_power_levels: false,
361        use_room_create_sender: false,
362        explicitly_privilege_room_creators: false,
363        additional_room_creators: false,
364        room_create_event_id_as_room_id: false,
365    };
366
367    /// Authorization rules with tweaks introduced in room version 3 ([spec]).
368    ///
369    /// [spec]: https://spec.matrix.org/latest/rooms/v3/#authorization-rules
370    pub const V3: Self = Self { special_case_room_redaction: false, ..Self::V1 };
371
372    /// Authorization rules with tweaks introduced in room version 6 ([spec]).
373    ///
374    /// [spec]: https://spec.matrix.org/latest/rooms/v6/#authorization-rules
375    pub const V6: Self = Self {
376        special_case_room_aliases: false,
377        strict_canonical_json: true,
378        limit_notifications_power_levels: true,
379        ..Self::V3
380    };
381
382    /// Authorization rules with tweaks introduced in room version 7 ([spec]).
383    ///
384    /// [spec]: https://spec.matrix.org/latest/rooms/v7/#authorization-rules
385    pub const V7: Self = Self { knocking: true, ..Self::V6 };
386
387    /// Authorization rules with tweaks introduced in room version 8 ([spec]).
388    ///
389    /// [spec]: https://spec.matrix.org/latest/rooms/v8/#authorization-rules
390    pub const V8: Self = Self { restricted_join_rule: true, ..Self::V7 };
391
392    /// Authorization rules with tweaks introduced in room version 10 ([spec]).
393    ///
394    /// [spec]: https://spec.matrix.org/latest/rooms/v10/#authorization-rules
395    pub const V10: Self =
396        Self { knock_restricted_join_rule: true, integer_power_levels: true, ..Self::V8 };
397
398    /// Authorization rules with tweaks introduced in room version 11 ([spec]).
399    ///
400    /// [spec]: https://spec.matrix.org/latest/rooms/v11/#authorization-rules
401    pub const V11: Self = Self { use_room_create_sender: true, ..Self::V10 };
402
403    /// Authorization rules with tweaks introduced in room version 12.
404    pub const V12: Self = Self {
405        explicitly_privilege_room_creators: true,
406        additional_room_creators: true,
407        room_create_event_id_as_room_id: true,
408        ..Self::V11
409    };
410}
411
412/// The tweaks in the [redaction] algorithm for a room version.
413///
414/// This type can be constructed from one of its constants (like [`RedactionRules::V1`]), or by
415/// constructing a [`RoomVersionRules`] first and using the `redaction` field.
416///
417/// [redaction]: https://spec.matrix.org/latest/client-server-api/#redactions
418#[derive(Debug, Clone)]
419#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
420pub struct RedactionRules {
421    /// Whether to keep the `aliases` field in the `content` of `m.room.aliases` events ([spec]),
422    /// disabled since room version 6.
423    ///
424    /// [spec]: https://spec.matrix.org/v1.15/rooms/v6/#redactions
425    pub keep_room_aliases_aliases: bool,
426
427    /// Whether to keep the `allow` field in the `content` of `m.room.join_rules` events ([spec]),
428    /// introduced in room version 8.
429    ///
430    /// [spec]: https://spec.matrix.org/v1.15/rooms/v8/#redactions
431    pub keep_room_join_rules_allow: bool,
432
433    /// Whether to keep the `join_authorised_via_users_server` field in the `content` of
434    /// `m.room.member` events ([spec]), introduced in room version 9.
435    ///
436    /// [spec]: https://spec.matrix.org/v1.15/rooms/v9/#redactions
437    pub keep_room_member_join_authorised_via_users_server: bool,
438
439    /// Whether to keep the `origin`, `membership` and `prev_state` fields a the top-level of all
440    /// events ([spec]), disabled since room version 11.
441    ///
442    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
443    pub keep_origin_membership_prev_state: bool,
444
445    /// Whether to keep the entire `content` of `m.room.create` events ([spec]), introduced in room
446    /// version 11.
447    ///
448    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
449    pub keep_room_create_content: bool,
450
451    /// Whether to keep the `redacts` field in the `content` of `m.room.redaction` events ([spec]),
452    /// introduced in room version 11.
453    ///
454    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
455    pub keep_room_redaction_redacts: bool,
456
457    /// Whether to keep the `invite` field in the `content` of `m.room.power_levels` events
458    /// ([spec]), introduced in room version 11.
459    ///
460    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
461    pub keep_room_power_levels_invite: bool,
462
463    /// Whether to keep the `signed` field in `third_party_invite` of the `content` of
464    /// `m.room.member` events ([spec]), introduced in room version 11.
465    ///
466    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
467    pub keep_room_member_third_party_invite_signed: bool,
468
469    /// Whether the `content.redacts` field should be used to determine the event an event
470    /// redacts, as opposed to the top-level `redacts` field ([spec]), introduced in room version
471    /// 11.
472    ///
473    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
474    pub content_field_redacts: bool,
475
476    /// Whether to keep the `allow`, `deny` and `allow_ip_literals` in the `content` of
477    /// `m.room.server_acl` events ([MSC2870]).
478    ///
479    /// [MSC2870]: https://github.com/matrix-org/matrix-spec-proposals/pull/2870
480    #[cfg(feature = "unstable-msc2870")]
481    pub keep_room_server_acl_allow_deny_allow_ip_literals: bool,
482}
483
484impl RedactionRules {
485    /// Redaction rules as introduced in room version 1 ([spec]).
486    ///
487    /// [spec]: https://spec.matrix.org/v1.15/rooms/v1/#redactions
488    pub const V1: Self = Self {
489        keep_room_aliases_aliases: true,
490        keep_room_join_rules_allow: false,
491        keep_room_member_join_authorised_via_users_server: false,
492        keep_origin_membership_prev_state: true,
493        keep_room_create_content: false,
494        keep_room_redaction_redacts: false,
495        keep_room_power_levels_invite: false,
496        keep_room_member_third_party_invite_signed: false,
497        content_field_redacts: false,
498        #[cfg(feature = "unstable-msc2870")]
499        keep_room_server_acl_allow_deny_allow_ip_literals: false,
500    };
501
502    /// Redaction rules with tweaks introduced in room version 6 ([spec]).
503    ///
504    /// [spec]: https://spec.matrix.org/v1.15/rooms/v6/#redactions
505    pub const V6: Self = Self { keep_room_aliases_aliases: false, ..Self::V1 };
506
507    /// Redaction rules with tweaks introduced in room version 8 ([spec]).
508    ///
509    /// [spec]: https://spec.matrix.org/v1.15/rooms/v8/#redactions
510    pub const V8: Self = Self { keep_room_join_rules_allow: true, ..Self::V6 };
511
512    /// Redaction rules with tweaks introduced in room version 9 ([spec]).
513    ///
514    /// [spec]: https://spec.matrix.org/v1.15/rooms/v9/#redactions
515    pub const V9: Self =
516        Self { keep_room_member_join_authorised_via_users_server: true, ..Self::V8 };
517
518    /// Redaction rules with tweaks introduced in room version 11 ([spec]).
519    ///
520    /// [spec]: https://spec.matrix.org/v1.15/rooms/v11/#redactions
521    pub const V11: Self = Self {
522        keep_origin_membership_prev_state: false,
523        keep_room_create_content: true,
524        keep_room_redaction_redacts: true,
525        keep_room_power_levels_invite: true,
526        keep_room_member_third_party_invite_signed: true,
527        content_field_redacts: true,
528        ..Self::V9
529    };
530
531    /// Redaction rules with tweaks introduced in [MSC2870].
532    ///
533    /// [MSC2870]: https://github.com/matrix-org/matrix-spec-proposals/pull/2870
534    #[cfg(feature = "unstable-msc2870")]
535    pub const MSC2870: Self =
536        Self { keep_room_server_acl_allow_deny_allow_ip_literals: true, ..Self::V11 };
537}
538
539/// The tweaks for [verifying the signatures] for a room version.
540///
541/// This type can be constructed from one of its constants (like [`SignaturesRules::V1`]), or by
542/// constructing a [`RoomVersionRules`] first and using the `signatures` field.
543///
544/// [verifying the signatures]: https://spec.matrix.org/latest/server-server-api/#validating-hashes-and-signatures-on-received-events
545#[derive(Debug, Clone)]
546#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
547pub struct SignaturesRules {
548    /// Whether to check the server of the event ID, disabled since room version 3.
549    pub check_event_id_server: bool,
550
551    /// Whether to check the server of the `join_authorised_via_users_server` field in the
552    /// `content` of `m.room.member` events ([spec]), introduced in room version 8.
553    ///
554    /// [spec]: https://spec.matrix.org/latest/rooms/v8/#authorization-rules
555    pub check_join_authorised_via_users_server: bool,
556}
557
558impl SignaturesRules {
559    /// Signatures verification rules as introduced in room version 1.
560    pub const V1: Self =
561        Self { check_event_id_server: true, check_join_authorised_via_users_server: false };
562
563    /// Signatures verification rules with tweaks introduced in room version 3.
564    pub const V3: Self = Self { check_event_id_server: false, ..Self::V1 };
565
566    /// Signatures verification rules with tweaks introduced in room version 8.
567    pub const V8: Self = Self { check_join_authorised_via_users_server: true, ..Self::V3 };
568}
569
570/// The tweaks for verifying the event format for a room version.
571///
572/// This type can be constructed from one of its constants (like [`EventFormatRules::V1`]), or by
573/// constructing a [`RoomVersionRules`] first and using the `event_format` field.
574#[derive(Debug, Clone)]
575#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
576pub struct EventFormatRules {
577    /// Whether the `event_id` field is required, disabled since room version 3.
578    pub require_event_id: bool,
579
580    /// Whether the `room_id` field is required on the `m.room.create` event, disabled since room
581    /// version 12.
582    pub require_room_create_room_id: bool,
583
584    /// Whether the `m.room.create` event is allowed to be in the `auth_events`, disabled since
585    /// room version 12.
586    pub allow_room_create_in_auth_events: bool,
587}
588
589impl EventFormatRules {
590    /// Event format rules as introduced in room version 1.
591    pub const V1: Self = Self {
592        require_event_id: true,
593        require_room_create_room_id: true,
594        allow_room_create_in_auth_events: true,
595    };
596
597    /// Event format rules with tweaks introduced in room version 3.
598    pub const V3: Self = Self { require_event_id: false, ..Self::V1 };
599
600    /// Event format rules with tweaks introduced in room version 12.
601    pub const V12: Self = Self {
602        require_room_create_room_id: false,
603        allow_room_create_in_auth_events: false,
604        ..Self::V3
605    };
606}
607
608/// The tweaks for determining the power level of a user.
609#[derive(Clone, Debug)]
610#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
611pub struct RoomPowerLevelsRules {
612    /// The creator(s) of the room which are considered to have "infinite" power level, introduced
613    /// in room version 12.
614    #[allow(clippy::disallowed_types)]
615    pub privileged_creators: Option<HashSet<OwnedUserId>>,
616}
617
618impl RoomPowerLevelsRules {
619    /// Creates a new `RoomPowerLevelsRules` from the given parameters, using the `creators` if
620    /// the rule `explicitly_privilege_room_creators` is `true`.
621    pub fn new(
622        rules: &AuthorizationRules,
623        creators: impl IntoIterator<Item = OwnedUserId>,
624    ) -> Self {
625        Self {
626            privileged_creators: rules
627                .explicitly_privilege_room_creators
628                .then(|| creators.into_iter().collect()),
629        }
630    }
631}