Optimize /sync response

This commit is contained in:
Timo Kösters 2020-06-07 12:08:25 +02:00 committed by GitHub
parent db4c0b2134
commit acff664671
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 114 additions and 16 deletions

View File

@ -1,5 +1,9 @@
# [unreleased] # [unreleased]
Bug fixes:
* More missing fields in `r0::sync::sync_events::Response` can be deserialized
Breaking changes: Breaking changes:
* Make `avatar_url` in `r0::profile::set_avatar_url::Request` an `Option` * Make `avatar_url` in `r0::profile::set_avatar_url::Request` an `Option`
@ -11,11 +15,13 @@ Breaking changes:
* Update `r0::push::get_pushrules_all` and `r0::push::get_pushrules_global_scope` to use the * Update `r0::push::get_pushrules_all` and `r0::push::get_pushrules_global_scope` to use the
`Ruleset` type from `ruma_events` `Ruleset` type from `ruma_events`
* Fix event types in `r0::context::get_context` * Fix event types in `r0::context::get_context`
* Fix event types in `r0::sync::sync_events`
Improvements: Improvements:
* Add method `into_event_content` for `r0::room::create_room::CreationContent` * Add method `into_event_content` for `r0::room::create_room::CreationContent`
* Add room visibility endpoints: `r0::directory::{get_room_visibility, set_room_visibility}`. * Add room visibility endpoints: `r0::directory::{get_room_visibility, set_room_visibility}`.
* Add is_empty helpers for structs in `r0::sync::sync_events`
Deprecations: Deprecations:

View File

@ -86,8 +86,8 @@ ruma_api! {
/// Information on E2E device updates. /// Information on E2E device updates.
/// ///
/// Only present on an incremental sync. /// Only present on an incremental sync.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "DeviceLists::is_empty")]
pub device_lists: Option<DeviceLists>, pub device_lists: DeviceLists,
/// For each key algorithm, the number of unclaimed one-time keys /// For each key algorithm, the number of unclaimed one-time keys
/// currently held on the server for a device. /// currently held on the server for a device.
@ -130,17 +130,21 @@ pub enum Filter {
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Rooms { pub struct Rooms {
/// The rooms that the user has left or been banned from. /// The rooms that the user has left or been banned from.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub leave: BTreeMap<RoomId, LeftRoom>, pub leave: BTreeMap<RoomId, LeftRoom>,
/// The rooms that the user has joined. /// The rooms that the user has joined.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub join: BTreeMap<RoomId, JoinedRoom>, pub join: BTreeMap<RoomId, JoinedRoom>,
/// The rooms that the user has been invited to. /// The rooms that the user has been invited to.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub invite: BTreeMap<RoomId, InvitedRoom>, pub invite: BTreeMap<RoomId, InvitedRoom>,
} }
impl Rooms { impl Rooms {
fn is_empty(&self) -> bool { /// Returns true if there is no update in any room.
pub fn is_empty(&self) -> bool {
self.leave.is_empty() && self.join.is_empty() && self.invite.is_empty() self.leave.is_empty() && self.join.is_empty() && self.invite.is_empty()
} }
} }
@ -150,14 +154,23 @@ impl Rooms {
pub struct LeftRoom { pub struct LeftRoom {
/// The timeline of messages and state changes in the room up to the point when the user /// The timeline of messages and state changes in the room up to the point when the user
/// left. /// left.
#[serde(default, skip_serializing_if = "Timeline::is_empty")]
pub timeline: Timeline, pub timeline: Timeline,
/// The state updates for the room up to the start of the timeline. /// The state updates for the room up to the start of the timeline.
#[serde(default, skip_serializing_if = "State::is_empty")]
pub state: State, pub state: State,
/// The private data that this user has attached to this room. /// The private data that this user has attached to this room.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "AccountData::is_empty")]
pub account_data: Option<AccountData>, pub account_data: AccountData,
}
impl LeftRoom {
/// Returns true if there are updates in the room.
pub fn is_empty(&self) -> bool {
self.timeline.is_empty() && self.state.is_empty() && self.account_data.is_empty()
}
} }
/// Updates to joined rooms. /// Updates to joined rooms.
@ -165,30 +178,47 @@ pub struct LeftRoom {
pub struct JoinedRoom { pub struct JoinedRoom {
/// Information about the room which clients may need to correctly render it /// Information about the room which clients may need to correctly render it
/// to users. /// to users.
#[serde(default, skip_serializing_if = "RoomSummary::is_empty")]
pub summary: RoomSummary, pub summary: RoomSummary,
/// Counts of unread notifications for this room. /// Counts of unread notifications for this room.
#[serde(default, skip_serializing_if = "UnreadNotificationsCount::is_empty")]
pub unread_notifications: UnreadNotificationsCount, pub unread_notifications: UnreadNotificationsCount,
/// The timeline of messages and state changes in the room. /// The timeline of messages and state changes in the room.
#[serde(default, skip_serializing_if = "Timeline::is_empty")]
pub timeline: Timeline, pub timeline: Timeline,
/// Updates to the state, between the time indicated by the `since` parameter, and the start /// Updates to the state, between the time indicated by the `since` parameter, and the start
/// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not /// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not
/// given, or `full_state` is true). /// given, or `full_state` is true).
#[serde(default, skip_serializing_if = "State::is_empty")]
pub state: State, pub state: State,
/// The private data that this user has attached to this room. /// The private data that this user has attached to this room.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "AccountData::is_empty")]
pub account_data: Option<AccountData>, pub account_data: AccountData,
/// The ephemeral events in the room that aren't recorded in the timeline or state of the /// The ephemeral events in the room that aren't recorded in the timeline or state of the
/// room. e.g. typing. /// room. e.g. typing.
#[serde(default, skip_serializing_if = "Ephemeral::is_empty")]
pub ephemeral: Ephemeral, pub ephemeral: Ephemeral,
} }
impl JoinedRoom {
/// Returns true if there are no updates in the room.
pub fn is_empty(&self) -> bool {
self.summary.is_empty()
&& self.unread_notifications.is_empty()
&& self.timeline.is_empty()
&& self.state.is_empty()
&& self.account_data.is_empty()
&& self.ephemeral.is_empty()
}
}
/// unread notifications count /// unread notifications count
#[derive(Clone, Copy, Debug, Deserialize, Serialize)] #[derive(Clone, Copy, Default, Debug, Deserialize, Serialize)]
pub struct UnreadNotificationsCount { pub struct UnreadNotificationsCount {
/// The number of unread notifications for this room with the highlight flag set. /// The number of unread notifications for this room with the highlight flag set.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -199,8 +229,15 @@ pub struct UnreadNotificationsCount {
pub notification_count: Option<UInt>, pub notification_count: Option<UInt>,
} }
impl UnreadNotificationsCount {
/// Returns true if there are no notification count updates.
pub fn is_empty(&self) -> bool {
self.highlight_count.is_none() && self.notification_count.is_none()
}
}
/// Events in the room. /// Events in the room.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Timeline { pub struct Timeline {
/// True if the number of events returned was limited by the `limit` on the filter. /// True if the number of events returned was limited by the `limit` on the filter.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -215,13 +252,27 @@ pub struct Timeline {
pub events: Vec<EventJson<RoomEvent>>, pub events: Vec<EventJson<RoomEvent>>,
} }
impl Timeline {
/// Returns true if there are no timeline updates.
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
}
/// State events in the room. /// State events in the room.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct State { pub struct State {
/// A list of state events. /// A list of state events.
pub events: Vec<EventJson<StateEvent>>, pub events: Vec<EventJson<StateEvent>>,
} }
impl State {
/// Returns true if there are no state updates.
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
}
/// The private data that this user has attached to this room. /// The private data that this user has attached to this room.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct AccountData { pub struct AccountData {
@ -230,20 +281,28 @@ pub struct AccountData {
} }
impl AccountData { impl AccountData {
fn is_empty(&self) -> bool { /// Returns true if there are no account data updates.
pub fn is_empty(&self) -> bool {
self.events.is_empty() self.events.is_empty()
} }
} }
/// Ephemeral events not recorded in the timeline or state of the room. /// Ephemeral events not recorded in the timeline or state of the room.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Ephemeral { pub struct Ephemeral {
/// A list of events. /// A list of events.
pub events: Vec<EventJson<NonRoomEvent>>, pub events: Vec<EventJson<NonRoomEvent>>,
} }
impl Ephemeral {
/// Returns true if there are no ephemeral event updates.
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
}
/// Information about room for rendering to clients. /// Information about room for rendering to clients.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct RoomSummary { pub struct RoomSummary {
/// Users which can be used to generate a room name if the room does not have /// Users which can be used to generate a room name if the room does not have
/// one. Required if room name or canonical aliases are not set or empty. /// one. Required if room name or canonical aliases are not set or empty.
@ -263,20 +322,44 @@ pub struct RoomSummary {
pub invited_member_count: Option<UInt>, pub invited_member_count: Option<UInt>,
} }
impl RoomSummary {
/// Returns true if there are no room summary updates.
pub fn is_empty(&self) -> bool {
self.heroes.is_empty()
&& self.joined_member_count.is_none()
&& self.invited_member_count.is_none()
}
}
/// Updates to the rooms that the user has been invited to. /// Updates to the rooms that the user has been invited to.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InvitedRoom { pub struct InvitedRoom {
/// The state of a room that the user has been invited to. /// The state of a room that the user has been invited to.
#[serde(default, skip_serializing_if = "InviteState::is_empty")]
pub invite_state: InviteState, pub invite_state: InviteState,
} }
impl InvitedRoom {
/// Returns true if there are no updates to this room.
pub fn is_empty(&self) -> bool {
self.invite_state.is_empty()
}
}
/// The state of a room that the user has been invited to. /// The state of a room that the user has been invited to.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct InviteState { pub struct InviteState {
/// A list of state events. /// A list of state events.
pub events: Vec<EventJson<AnyStrippedStateEvent>>, pub events: Vec<EventJson<AnyStrippedStateEvent>>,
} }
impl InviteState {
/// Returns true if there are no state updates.
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
}
/// Updates to the presence status of other users. /// Updates to the presence status of other users.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Presence { pub struct Presence {
@ -285,7 +368,8 @@ pub struct Presence {
} }
impl Presence { impl Presence {
fn is_empty(&self) -> bool { /// Returns true if there are no presence updates.
pub fn is_empty(&self) -> bool {
self.events.is_empty() self.events.is_empty()
} }
} }
@ -298,13 +382,14 @@ pub struct ToDevice {
} }
impl ToDevice { impl ToDevice {
/// Returns true if there are no to-device events.
fn is_empty(&self) -> bool { fn is_empty(&self) -> bool {
self.events.is_empty() self.events.is_empty()
} }
} }
/// Information on E2E device udpates. /// Information on E2E device udpates.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct DeviceLists { pub struct DeviceLists {
/// List of users who have updated their device identity keys or who now /// List of users who have updated their device identity keys or who now
/// share an encrypted room with the client since the previous sync /// share an encrypted room with the client since the previous sync
@ -317,6 +402,13 @@ pub struct DeviceLists {
pub left: Vec<UserId>, pub left: Vec<UserId>,
} }
impl DeviceLists {
/// Returns true if there are no device list updates.
fn is_empty(&self) -> bool {
self.changed.is_empty() && self.left.is_empty()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{convert::TryInto, time::Duration}; use std::{convert::TryInto, time::Duration};