client-api: Update sliding sync to latest

This commit is contained in:
Benjamin Kampmann 2022-09-21 18:11:32 +02:00 committed by GitHub
parent b715911189
commit efc5e61021
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 234 additions and 34 deletions

View File

@ -1,5 +1,11 @@
# [unreleased]
Improvements:
* `DeviceLists` has moved from `sync::sync_events::v3` to `sync::sync_events`
* It is still available under the old location for backwards compatibility
# 0.15.0
Breaking changes:

View File

@ -1,6 +1,7 @@
//! `GET /_matrix/client/*/sync`
use js_int::UInt;
use ruma_common::OwnedUserId;
use serde::{self, Deserialize, Serialize};
pub mod v3;
@ -32,3 +33,30 @@ impl UnreadNotificationsCount {
self.highlight_count.is_none() && self.notification_count.is_none()
}
}
/// Information on E2E device updates.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct DeviceLists {
/// List of users who have updated their device identity keys or who now
/// share an encrypted room with the client since the previous sync.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub changed: Vec<OwnedUserId>,
/// List of users who no longer share encrypted rooms since the previous sync
/// response.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub left: Vec<OwnedUserId>,
}
impl DeviceLists {
/// Creates an empty `DeviceLists`.
pub fn new() -> Self {
Default::default()
}
/// Returns true if there are no device list updates.
pub fn is_empty(&self) -> bool {
self.changed.is_empty() && self.left.is_empty()
}
}

View File

@ -4,6 +4,7 @@
use std::{collections::BTreeMap, time::Duration};
pub use super::DeviceLists;
use super::UnreadNotificationsCount;
use js_int::UInt;
use ruma_common::{
@ -15,7 +16,7 @@ use ruma_common::{
},
presence::PresenceState,
serde::{Incoming, Raw},
DeviceKeyAlgorithm, OwnedRoomId, OwnedUserId,
DeviceKeyAlgorithm, OwnedRoomId,
};
use serde::{Deserialize, Serialize};
@ -579,33 +580,6 @@ impl ToDevice {
}
}
/// Information on E2E device updates.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct DeviceLists {
/// List of users who have updated their device identity keys or who now
/// share an encrypted room with the client since the previous sync
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub changed: Vec<OwnedUserId>,
/// List of users who no longer share encrypted rooms since the previous sync
/// response.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub left: Vec<OwnedUserId>,
}
impl DeviceLists {
/// Creates an empty `DeviceLists`.
pub fn new() -> Self {
Default::default()
}
/// Returns true if there are no device list updates.
pub fn is_empty(&self) -> bool {
self.changed.is_empty() && self.left.is_empty()
}
}
#[cfg(test)]
mod tests {
use assign::assign;

View File

@ -2,13 +2,16 @@
use std::{collections::BTreeMap, time::Duration};
use super::UnreadNotificationsCount;
use super::{DeviceLists, UnreadNotificationsCount};
use js_int::UInt;
use ruma_common::{
api::ruma_api,
events::{AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent, RoomEventType},
events::{
AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnyStrippedStateEvent,
AnySyncStateEvent, AnySyncTimelineEvent, AnyToDeviceEvent, RoomEventType,
},
serde::{duration::opt_ms, Raw},
OwnedRoomId,
DeviceKeyAlgorithm, OwnedRoomId,
};
use serde::{Deserialize, Serialize};
@ -60,8 +63,8 @@ ruma_api! {
pub unsubscribe_rooms: &'a [OwnedRoomId],
/// Extensions API.
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub extensions: BTreeMap<String, serde_json::Value>,
#[serde(default, skip_serializing_if = "ExtensionsConfig::is_empty")]
pub extensions: ExtensionsConfig,
}
response: {
@ -80,6 +83,10 @@ ruma_api! {
/// The updates on rooms.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub rooms: BTreeMap<OwnedRoomId, SlidingSyncRoom>,
/// Extensions API.
#[serde(default, skip_serializing_if = "Extensions::is_empty")]
pub extensions: Extensions,
}
error: crate::Error
@ -100,9 +107,11 @@ impl Response {
pos,
lists: Default::default(),
rooms: Default::default(),
extensions: Default::default(),
}
}
}
/// Filter for a sliding sync list, set at request.
///
/// All fields are applied with AND operators, hence if `is_dm` is `true` and `is_encrypted` is
@ -162,7 +171,7 @@ pub struct SyncRequestListFilters {
/// of the strings in this array will be returned. If this field is unset, all rooms are
/// returned regardless of type. This can be used to get the initial set of spaces for an
/// account.
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub room_types: Vec<String>,
/// Only list rooms that are not of these create-types, or all.
@ -176,8 +185,25 @@ pub struct SyncRequestListFilters {
///
/// Filter the room name. Case-insensitive partial matching e.g 'foo' matches 'abFooab'.
/// The term 'like' is inspired by SQL 'LIKE', and the text here is similar to '%foo%'.
#[serde(skip_serializing_if = "Option::is_none")]
pub room_name_like: Option<String>,
/// Filter the room based on its room tags.
///
/// If multiple tags are present, a room can have
/// any one of the listed tags (OR'd).
#[serde(default, skip_serializing_if = "<[_]>::is_empty")]
pub tags: Vec<String>,
/// Filter the room based on its room tags.
///
/// Takes priority over `tags`. For example, a room
/// with tags A and B with filters `tags:[A]` `not_tags:[B]` would NOT be included because
/// `not_tags` takes priority over `tags`. This filter is useful if your Rooms list does
/// NOT include the list of favourite rooms again.
#[serde(default, skip_serializing_if = "<[_]>::is_empty")]
pub not_tags: Vec<String>,
/// Extensions may add further fields to the filters.
#[serde(flatten, default, skip_serializing_if = "BTreeMap::is_empty")]
pub extensions: BTreeMap<String, serde_json::Value>,
@ -325,6 +351,18 @@ pub struct SlidingSyncRoom {
/// The prev_batch allowing you to paginate through the messages before the given ones.
#[serde(skip_serializing_if = "Option::is_none")]
pub prev_batch: Option<String>,
/// True if the number of events returned was limited by the limit on the filter.
#[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
pub limited: bool,
/// The number of users with membership of `join`, including the clients own user ID.
#[serde(skip_serializing_if = "Option::is_none")]
pub joined_count: Option<UInt>,
/// The number of users with membership of `invite`.
#[serde(skip_serializing_if = "Option::is_none")]
pub invited_count: Option<UInt>,
}
impl SlidingSyncRoom {
@ -333,3 +371,157 @@ impl SlidingSyncRoom {
Default::default()
}
}
/// Sliding-Sync extension configuration.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ExtensionsConfig {
/// Request to devices messages with the given config.
#[serde(skip_serializing_if = "Option::is_none")]
pub to_device: Option<ToDeviceConfig>,
/// Configure the end-to-end-encryption extension.
#[serde(skip_serializing_if = "Option::is_none")]
pub e2ee: Option<E2EEConfig>,
/// Configure the account data extension.
#[serde(skip_serializing_if = "Option::is_none")]
pub account_data: Option<AccountDataConfig>,
/// Extensions may add further fields to the list.
#[serde(flatten)]
other: BTreeMap<String, serde_json::Value>,
}
impl ExtensionsConfig {
fn is_empty(&self) -> bool {
self.to_device.is_none()
&& self.e2ee.is_none()
&& self.account_data.is_none()
&& self.other.is_empty()
}
}
/// Extensions specific response data.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Extensions {
/// To-device extension in response.
#[serde(skip_serializing_if = "Option::is_none")]
pub to_device: Option<ToDevice>,
/// E2EE extension in response.
#[serde(skip_serializing_if = "Option::is_none")]
pub e2ee: Option<E2EE>,
/// Account data extension in response.
#[serde(skip_serializing_if = "Option::is_none")]
pub account_data: Option<AccountData>,
}
impl Extensions {
/// Whether extension data was given.
///
/// True if neither to-device, e2ee nor account data are to be found.
pub fn is_empty(&self) -> bool {
self.to_device.is_none() && self.e2ee.is_none() && self.account_data.is_none()
}
}
/// To-device messages extension configuration.
///
/// According to [MSC3885](https://github.com/matrix-org/matrix-spec-proposals/pull/3885).
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ToDeviceConfig {
/// Activate or deactivate this extension. Sticky.
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
/// Max number of to-device messages per response.
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<UInt>,
/// Give messages since this token only.
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option<String>,
}
/// To-device messages extension response.
///
/// According to [MSC3885](https://github.com/matrix-org/matrix-spec-proposals/pull/3885).
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ToDevice {
/// Fetch the next batch from this entry.
pub next_batch: String,
/// The to-device Events.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub events: Vec<Raw<AnyToDeviceEvent>>,
}
/// E2EE extension configuration.
///
/// According to [MSC3884](https://github.com/matrix-org/matrix-spec-proposals/pull/3884).
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct E2EEConfig {
/// Activate or deactivate this extension. Sticky.
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
}
/// E2EE extension response data.
///
/// According to [MSC3884](https://github.com/matrix-org/matrix-spec-proposals/pull/3884).
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct E2EE {
/// Information on E2EE device updates.
///
/// Only present on an incremental sync.
#[serde(default, skip_serializing_if = "DeviceLists::is_empty")]
pub device_lists: DeviceLists,
/// For each key algorithm, the number of unclaimed one-time keys
/// currently held on the server for a device.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub device_one_time_keys_count: BTreeMap<DeviceKeyAlgorithm, UInt>,
/// For each key algorithm, the number of unclaimed one-time keys
/// currently held on the server for a device.
///
/// The presence of this field indicates that the server supports
/// fallback keys.
#[serde(skip_serializing_if = "Option::is_none")]
pub device_unused_fallback_key_types: Option<Vec<DeviceKeyAlgorithm>>,
}
/// Account-data extension configuration.
///
/// Not yet part of the spec proposal. Taken from the reference implementation
/// <https://github.com/matrix-org/sliding-sync/blob/d77e21138d4886d27b3888d36cf3627f54f67590/sync3/extensions/account_data.go>
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct AccountDataConfig {
/// Activate or deactivate this extension. Sticky.
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
}
/// Account-data extension response data.
///
/// Not yet part of the spec proposal. Taken from the reference implementation
/// <https://github.com/matrix-org/sliding-sync/blob/d77e21138d4886d27b3888d36cf3627f54f67590/sync3/extensions/account_data.go>
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct AccountData {
/// The global private data created by this user.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub global: Vec<Raw<AnyGlobalAccountDataEvent>>,
/// The private data that this user has attached to each room.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub rooms: BTreeMap<OwnedRoomId, Vec<Raw<AnyRoomAccountDataEvent>>>,
}