diff --git a/ruma-common/src/directory.rs b/ruma-common/src/directory.rs index eb723a8b..85d61028 100644 --- a/ruma-common/src/directory.rs +++ b/ruma-common/src/directory.rs @@ -12,8 +12,12 @@ use serde::{ use serde_json::Value as JsonValue; -/// A chunk of a room list response, describing one room +/// A chunk of a room list response, describing one room. +/// +/// To create an instance of this type, first create a `PublicRoomsChunkInit` and convert it via +/// `PublicRoomsChunk::from` / `.into()`. #[derive(Clone, Debug, Deserialize, Serialize)] +#[non_exhaustive] pub struct PublicRoomsChunk { /// Aliases of the room. #[serde(default, skip_serializing_if = "Vec::is_empty")] @@ -50,17 +54,66 @@ pub struct PublicRoomsChunk { pub avatar_url: Option, } +/// Initial set of mandatory fields of `PublicRoomsChunk`. +/// +/// This struct will not be updated even if additional fields are added to `PublicRoomsChunk` in a +/// new (non-breaking) release of the Matrix specification. +#[derive(Debug)] +pub struct PublicRoomsChunkInit { + /// The number of members joined to the room. + pub num_joined_members: UInt, + + /// The ID of the room. + pub room_id: RoomId, + + /// Whether the room may be viewed by guest users without joining. + pub world_readable: bool, + + /// Whether guest users may join the room and participate in it. + /// + /// If they can, they will be subject to ordinary power level rules like any other user. + pub guest_can_join: bool, +} + +impl From for PublicRoomsChunk { + fn from(init: PublicRoomsChunkInit) -> Self { + let PublicRoomsChunkInit { num_joined_members, room_id, world_readable, guest_can_join } = + init; + + Self { + aliases: Vec::new(), + canonical_alias: None, + name: None, + num_joined_members, + room_id, + topic: None, + world_readable, + guest_can_join, + avatar_url: None, + } + } +} + /// A filter for public rooms lists -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[non_exhaustive] pub struct Filter { /// A string to search for in the room metadata, e.g. name, topic, canonical alias etc. #[serde(skip_serializing_if = "Option::is_none")] pub generic_search_term: Option, } +impl Filter { + /// Creates an empty `Filter`. + pub fn new() -> Self { + Default::default() + } +} + /// Information about which networks/protocols from application services on the /// homeserver from which to request rooms. #[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] pub enum RoomNetwork { /// Return rooms from the Matrix network. Matrix, diff --git a/ruma-common/src/encryption.rs b/ruma-common/src/encryption.rs index ec3d3118..e5550fb2 100644 --- a/ruma-common/src/encryption.rs +++ b/ruma-common/src/encryption.rs @@ -8,7 +8,8 @@ use ruma_identifiers::{DeviceIdBox, DeviceKeyId, EventEncryptionAlgorithm, UserI use serde::{Deserialize, Serialize}; /// Identity keys for a device. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] +#[non_exhaustive] pub struct DeviceKeys { /// The ID of the user the device belongs to. Must match the user ID used when logging in. pub user_id: UserId, @@ -27,13 +28,40 @@ pub struct DeviceKeys { /// Additional data added to the device key information by intermediate servers, and /// not covered by the signatures. - #[serde(skip_serializing_if = "Option::is_none")] - pub unsigned: Option, + #[serde(skip_serializing_if = "UnsignedDeviceInfo::is_empty")] + pub unsigned: UnsignedDeviceInfo, +} + +impl DeviceKeys { + /// Creates a new `DeviceKeys` from the given user id, device id, algorithms, keys and + /// signatures. + pub fn new( + user_id: UserId, + device_id: DeviceIdBox, + algorithms: Vec, + keys: BTreeMap, + signatures: BTreeMap>, + ) -> Self { + Self { user_id, device_id, algorithms, keys, signatures, unsigned: Default::default() } + } } /// Additional data added to device key information by intermediate servers. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct UnsignedDeviceInfo { /// The display name which the user set on the device. + #[serde(skip_serializing_if = "Option::is_none")] pub device_display_name: Option, } + +impl UnsignedDeviceInfo { + /// Creates an empty `UnsignedDeviceInfo`. + pub fn new() -> Self { + Default::default() + } + + /// Checks whether all fields are empty / `None`. + pub fn is_empty(&self) -> bool { + self.device_display_name.is_none() + } +} diff --git a/ruma-common/src/push.rs b/ruma-common/src/push.rs index 8bd3aafe..033650e3 100644 --- a/ruma-common/src/push.rs +++ b/ruma-common/src/push.rs @@ -18,9 +18,6 @@ pub use self::{ /// /// For example, some rules may only be applied for messages from a particular sender, a particular /// room, or by default. The push ruleset contains the entire set of scopes and rules. -/// -/// To create an instance of this type, use its `Default` implementation and set the fields you -/// need. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[non_exhaustive] pub struct Ruleset { @@ -45,6 +42,13 @@ pub struct Ruleset { pub underride: Vec, } +impl Ruleset { + /// Creates an empty `Ruleset`. + pub fn new() -> Self { + Default::default() + } +} + /// A push rule is a single rule that states under what conditions an event should be passed onto a /// push gateway and how the notification should be presented. ///