events: Make more types non-exhaustive

This commit is contained in:
Jonas Platte 2021-05-16 23:42:23 +02:00
parent 4dd9baa238
commit 76c9c56471
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
10 changed files with 136 additions and 12 deletions

View File

@ -14,8 +14,16 @@ pub type FullyReadEvent = RoomAccountDataEvent<FullyReadEventContent>;
/// The payload for `FullyReadEvent`. /// The payload for `FullyReadEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)] #[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.fully_read", kind = RoomAccountData)] #[ruma_event(type = "m.fully_read", kind = RoomAccountData)]
pub struct FullyReadEventContent { pub struct FullyReadEventContent {
/// The event the user's read marker is located at in the room. /// The event the user's read marker is located at in the room.
pub event_id: EventId, pub event_id: EventId,
} }
impl FullyReadEventContent {
/// Creates a new `FullyReadEventContent` with the given event ID.
pub fn new(event_id: EventId) -> Self {
Self { event_id }
}
}

View File

@ -85,14 +85,23 @@ pub enum ShortAuthenticationString {
/// The relation that contains info which event the reaction is applying to. /// The relation that contains info which event the reaction is applying to.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(try_from = "RelatesToJsonRepr", into = "RelatesToJsonRepr")]
#[cfg(feature = "unstable-pre-spec")] #[cfg(feature = "unstable-pre-spec")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))] #[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(try_from = "RelatesToJsonRepr", into = "RelatesToJsonRepr")]
pub struct Relation { pub struct Relation {
/// The event that is being referenced. /// The event that is being referenced.
pub event_id: EventId, pub event_id: EventId,
} }
#[cfg(feature = "unstable-pre-spec")]
impl Relation {
/// Creates a new `Relation` with the given event ID.
pub fn new(event_id: EventId) -> Self {
Self { event_id }
}
}
#[cfg(feature = "unstable-pre-spec")] #[cfg(feature = "unstable-pre-spec")]
impl From<Relation> for RelatesToJsonRepr { impl From<Relation> for RelatesToJsonRepr {
fn from(relation: Relation) -> Self { fn from(relation: Relation) -> Self {

View File

@ -20,9 +20,9 @@ pub struct PresenceEvent {
/// Informs the room of members presence. /// Informs the room of members presence.
/// ///
/// This is the only event content a `PresenceEvent` can contain as it's /// This is the only type a `PresenceEvent` can contain as its `content` field.
/// `content` field.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)] #[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.presence")] #[ruma_event(type = "m.presence")]
pub struct PresenceEventContent { pub struct PresenceEventContent {
/// The current avatar URL for this user. /// The current avatar URL for this user.
@ -56,6 +56,20 @@ pub struct PresenceEventContent {
pub status_msg: Option<String>, pub status_msg: Option<String>,
} }
impl PresenceEventContent {
/// Creates a new `PresenceEventContent` with the given state.
pub fn new(presence: PresenceState) -> Self {
Self {
avatar_url: None,
currently_active: None,
displayname: None,
last_active_ago: None,
presence,
status_msg: None,
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use js_int::uint; use js_int::uint;

View File

@ -11,12 +11,29 @@ pub type PushRulesEvent = GlobalAccountDataEvent<PushRulesEventContent>;
/// The payload for `PushRulesEvent`. /// The payload for `PushRulesEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)] #[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.push_rules", kind = GlobalAccountData)] #[ruma_event(type = "m.push_rules", kind = GlobalAccountData)]
pub struct PushRulesEventContent { pub struct PushRulesEventContent {
/// The global ruleset. /// The global ruleset.
pub global: Ruleset, pub global: Ruleset,
} }
impl PushRulesEventContent {
/// Creates a new `PushRulesEventContent` with the given global ruleset.
///
/// You can also construct a `PushRulesEventContent` from a global ruleset using `From` /
/// `Into`.
pub fn new(global: Ruleset) -> Self {
Self { global }
}
}
impl From<Ruleset> for PushRulesEventContent {
fn from(global: Ruleset) -> Self {
Self::new(global)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json::{from_value as from_json_value, json}; use serde_json::{from_value as from_json_value, json};

View File

@ -16,6 +16,7 @@ pub type ReactionEvent = MessageEvent<ReactionEventContent>;
/// The payload for a `ReactionEvent`. /// The payload for a `ReactionEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)] #[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.reaction", kind = Message)] #[ruma_event(type = "m.reaction", kind = Message)]
pub struct ReactionEventContent { pub struct ReactionEventContent {
/// Information about the related event. /// Information about the related event.
@ -23,8 +24,24 @@ pub struct ReactionEventContent {
pub relation: Relation, pub relation: Relation,
} }
impl ReactionEventContent {
/// Creates a new `ReactionEventContent` from the given relation.
///
/// You can also construct a `ReactionEventContent` from a relation using `From` / `Into`.
pub fn new(relation: Relation) -> Self {
Self { relation }
}
}
impl From<Relation> for ReactionEventContent {
fn from(relation: Relation) -> Self {
Self::new(relation)
}
}
/// The relation that contains info which event the reaction is applying to. /// The relation that contains info which event the reaction is applying to.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(try_from = "RelatesToJsonRepr", into = "RelatesToJsonRepr")] #[serde(try_from = "RelatesToJsonRepr", into = "RelatesToJsonRepr")]
pub struct Relation { pub struct Relation {
/// The event that is being reacted to. /// The event that is being reacted to.
@ -34,6 +51,13 @@ pub struct Relation {
pub emoji: String, pub emoji: String,
} }
impl Relation {
/// Creates a new `Relation` with the given event ID and emoji.
pub fn new(event_id: EventId, emoji: String) -> Self {
Self { event_id, emoji }
}
}
impl From<Relation> for RelatesToJsonRepr { impl From<Relation> for RelatesToJsonRepr {
fn from(relation: Relation) -> Self { fn from(relation: Relation) -> Self {
RelatesToJsonRepr::Relation(RelationJsonRepr::Annotation(Annotation { RelatesToJsonRepr::Relation(RelationJsonRepr::Annotation(Annotation {

View File

@ -46,9 +46,19 @@ pub type Receipts = BTreeMap<ReceiptType, UserReceipts>;
pub type UserReceipts = BTreeMap<UserId, Receipt>; pub type UserReceipts = BTreeMap<UserId, Receipt>;
/// An acknowledgement of an event. /// An acknowledgement of an event.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Receipt { pub struct Receipt {
/// The time when the receipt was sent. /// The time when the receipt was sent.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub ts: Option<MilliSecondsSinceUnixEpoch>, pub ts: Option<MilliSecondsSinceUnixEpoch>,
} }
impl Receipt {
/// Creates a new `Receipt` with the given timestamp.
///
/// To create an empty receipt instead, use [`Receipt::default`].
pub fn new(ts: MilliSecondsSinceUnixEpoch) -> Self {
Self { ts: Some(ts) }
}
}

View File

@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
/// ///
/// Typically encrypted as an *m.room.encrypted* event, then sent as a to-device event. /// Typically encrypted as an *m.room.encrypted* event, then sent as a to-device event.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)] #[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.room_key", kind = ToDevice)] #[ruma_event(type = "m.room_key", kind = ToDevice)]
pub struct RoomKeyToDeviceEventContent { pub struct RoomKeyToDeviceEventContent {
/// The encryption algorithm the key in this event is to be used with. /// The encryption algorithm the key in this event is to be used with.
@ -25,6 +26,19 @@ pub struct RoomKeyToDeviceEventContent {
pub session_key: String, pub session_key: String,
} }
impl RoomKeyToDeviceEventContent {
/// Creates a new `RoomKeyToDeviceEventContent` with the given algorithm, room ID, session ID
/// and session key.
pub fn new(
algorithm: EventEncryptionAlgorithm,
room_id: RoomId,
session_id: String,
session_key: String,
) -> Self {
Self { algorithm, room_id, session_id, session_key }
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ruma_identifiers::{room_id, user_id, EventEncryptionAlgorithm}; use ruma_identifiers::{room_id, user_id, EventEncryptionAlgorithm};

View File

@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
/// The payload for `RoomKeyRequestEvent`. /// The payload for `RoomKeyRequestEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)] #[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.room_key_request", kind = ToDevice)] #[ruma_event(type = "m.room_key_request", kind = ToDevice)]
pub struct RoomKeyRequestToDeviceEventContent { pub struct RoomKeyRequestToDeviceEventContent {
/// Whether this is a new key request or a cancellation of a previous request. /// Whether this is a new key request or a cancellation of a previous request.
@ -14,7 +15,7 @@ pub struct RoomKeyRequestToDeviceEventContent {
/// Information about the requested key. /// Information about the requested key.
/// ///
/// Required when action is `request`. /// Required if action is `request`.
pub body: Option<RequestedKeyInfo>, pub body: Option<RequestedKeyInfo>,
/// ID of the device requesting the key. /// ID of the device requesting the key.
@ -27,6 +28,19 @@ pub struct RoomKeyRequestToDeviceEventContent {
pub request_id: String, pub request_id: String,
} }
impl RoomKeyRequestToDeviceEventContent {
/// Creates a new `RoomKeyRequestToDeviceEventContent` with the given action, boyd, device ID
/// and request ID.
pub fn new(
action: Action,
body: Option<RequestedKeyInfo>,
requesting_device_id: DeviceIdBox,
request_id: String,
) -> Self {
Self { action, body, requesting_device_id, request_id }
}
}
/// A new key request or a cancellation of a previous request. /// A new key request or a cancellation of a previous request.
#[derive(Clone, Debug, PartialEq, Eq, StringEnum)] #[derive(Clone, Debug, PartialEq, Eq, StringEnum)]
#[ruma_enum(rename_all = "snake_case")] #[ruma_enum(rename_all = "snake_case")]
@ -44,6 +58,7 @@ pub enum Action {
/// Information about a requested key. /// Information about a requested key.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct RequestedKeyInfo { pub struct RequestedKeyInfo {
/// The encryption algorithm the requested key in this event is to be used with. /// The encryption algorithm the requested key in this event is to be used with.
pub algorithm: EventEncryptionAlgorithm, pub algorithm: EventEncryptionAlgorithm,
@ -57,3 +72,16 @@ pub struct RequestedKeyInfo {
/// The ID of the session that the key is for. /// The ID of the session that the key is for.
pub session_id: String, pub session_id: String,
} }
impl RequestedKeyInfo {
/// Creates a new `RequestedKeyInfo` with the given algorithm, room ID, sender key and session
/// ID.
pub fn new(
algorithm: EventEncryptionAlgorithm,
room_id: RoomId,
sender_key: String,
session_id: String,
) -> Self {
Self { algorithm, room_id, sender_key, session_id }
}
}

View File

@ -65,7 +65,7 @@ fn ephemeral_serialize_receipt() {
content: AnyEphemeralRoomEventContent::Receipt(ReceiptEventContent(btreemap! { content: AnyEphemeralRoomEventContent::Receipt(ReceiptEventContent(btreemap! {
event_id => btreemap! { event_id => btreemap! {
ReceiptType::Read => btreemap! { ReceiptType::Read => btreemap! {
user_id => Receipt { ts: Some(MilliSecondsSinceUnixEpoch(uint!(1))) }, user_id => Receipt::new(MilliSecondsSinceUnixEpoch(uint!(1))),
}, },
}, },
})), })),

View File

@ -6,12 +6,12 @@ use serde_json::{json, to_value as to_json_value};
fn serialization() { fn serialization() {
let ev = ToDeviceEvent { let ev = ToDeviceEvent {
sender: user_id!("@example:example.org"), sender: user_id!("@example:example.org"),
content: AnyToDeviceEventContent::RoomKey(RoomKeyToDeviceEventContent { content: AnyToDeviceEventContent::RoomKey(RoomKeyToDeviceEventContent::new(
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2, EventEncryptionAlgorithm::MegolmV1AesSha2,
room_id: room_id!("!testroomid:example.org"), room_id!("!testroomid:example.org"),
session_id: "SessId".into(), "SessId".into(),
session_key: "SessKey".into(), "SessKey".into(),
}), )),
}; };
assert_eq!( assert_eq!(