1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
//! [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-sync) use std::collections::HashMap; use js_int::UInt; use ruma_api::{ruma_api, Outgoing}; use ruma_events::{ collections::{all, only}, stripped, EventResult, }; use ruma_identifiers::RoomId; use serde::{Deserialize, Serialize}; use crate::r0::filter::FilterDefinition; ruma_api! { metadata { description: "Get all new events from all rooms since the last sync or a given point of time.", method: GET, name: "sync", path: "/_matrix/client/r0/sync", rate_limited: false, requires_authentication: true, } request { /// A filter represented either as its full JSON definition or the ID of a saved filter. #[serde(skip_serializing_if = "Option::is_none")] #[ruma_api(query)] pub filter: Option<Filter>, /// A point in time to continue a sync from. #[serde(skip_serializing_if = "Option::is_none")] #[ruma_api(query)] pub since: Option<String>, /// Controls whether to include the full state for all rooms the user is a member of. #[serde(skip_serializing_if = "Option::is_none")] #[ruma_api(query)] pub full_state: Option<bool>, /// Controls whether the client is automatically marked as online by polling this API. #[serde(skip_serializing_if = "Option::is_none")] #[ruma_api(query)] pub set_presence: Option<SetPresence>, /// The maximum time to poll in milliseconds before returning this request. #[serde(skip_serializing_if = "Option::is_none")] #[ruma_api(query)] pub timeout: Option<UInt>, } response { /// The batch token to supply in the `since` param of the next `/sync` request. pub next_batch: String, /// Updates to rooms. #[wrap_incoming] pub rooms: Rooms, /// Updates to the presence status of other users. #[wrap_incoming] pub presence: Presence, } } /// Whether to set presence or not during sync. #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub enum SetPresence { /// Do not set the presence of the user calling this API. #[serde(rename = "offline")] Offline, } /// A filter represented either as its full JSON definition or the ID of a saved filter. #[derive(Clone, Debug, Deserialize, Serialize)] #[allow(clippy::large_enum_variant)] #[serde(untagged)] pub enum Filter { // The filter definition needs to be (de)serialized twice because it is a URL-encoded JSON // string. Since #[ruma_api(query)] only does the latter and this is a very uncommon // setup, we implement it through custom serde logic for this specific enum variant rather than // adding another ruma_api attribute. // // On the deserialization side, because this is an enum with #[serde(untagged)], serde will // try the variants in order (https://serde.rs/enum-representations.html). That means because // FilterDefinition is the first variant, JSON decoding is attempted first which is almost // functionally equivalent to looking at whether the first symbol is a '{' as the spec says. // (there are probably some corner cases like leading whitespace) #[serde(with = "filter_def_serde")] /// A complete filter definition serialized to JSON. FilterDefinition(FilterDefinition), /// The ID of a filter saved on the server. FilterId(String), } /// Serialization and deserialization logic for filter definitions. mod filter_def_serde { use serde::{de::Error as _, ser::Error as _, Deserialize, Deserializer, Serializer}; use crate::r0::filter::FilterDefinition; /// Serialization logic for filter definitions. pub fn serialize<S>(filter_def: &FilterDefinition, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { let string = serde_json::to_string(filter_def).map_err(S::Error::custom)?; serializer.serialize_str(&string) } /// Deserialization logic for filter definitions. pub fn deserialize<'de, D>(deserializer: D) -> Result<FilterDefinition, D::Error> where D: Deserializer<'de>, { let filter_str = <&str>::deserialize(deserializer)?; serde_json::from_str(filter_str).map_err(D::Error::custom) } } /// Updates to rooms. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct Rooms { /// The rooms that the user has left or been banned from. #[wrap_incoming(LeftRoom)] pub leave: HashMap<RoomId, LeftRoom>, /// The rooms that the user has joined. #[wrap_incoming(JoinedRoom)] pub join: HashMap<RoomId, JoinedRoom>, /// The rooms that the user has been invited to. #[wrap_incoming(InvitedRoom)] pub invite: HashMap<RoomId, InvitedRoom>, } /// Historical updates to left rooms. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct LeftRoom { /// The timeline of messages and state changes in the room up to the point when the user /// left. #[wrap_incoming] pub timeline: Timeline, /// The state updates for the room up to the start of the timeline. #[wrap_incoming] pub state: State, } /// Updates to joined rooms. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct JoinedRoom { /// Counts of unread notifications for this room. pub unread_notifications: UnreadNotificationsCount, /// The timeline of messages and state changes in the room. #[wrap_incoming] pub timeline: Timeline, /// 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 /// given, or `full_state` is true). #[wrap_incoming] pub state: State, /// The private data that this user has attached to this room. #[wrap_incoming] pub account_data: AccountData, /// The ephemeral events in the room that aren't recorded in the timeline or state of the /// room. e.g. typing. #[wrap_incoming] pub ephemeral: Ephemeral, } /// unread notifications count #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct UnreadNotificationsCount { /// The number of unread notifications for this room with the highlight flag set. #[serde(skip_serializing_if = "Option::is_none")] pub highlight_count: Option<UInt>, /// The total number of unread notifications for this room. #[serde(skip_serializing_if = "Option::is_none")] pub notification_count: Option<UInt>, } /// Events in the room. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct Timeline { /// True if the number of events returned was limited by the `limit` on the filter. pub limited: bool, /// A token that can be supplied to to the `from` parameter of the /// `/rooms/{roomId}/messages` endpoint. pub prev_batch: String, /// A list of events. #[wrap_incoming(all::RoomEvent with EventResult)] pub events: Vec<all::RoomEvent>, } /// State events in the room. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct State { /// A list of state events. #[wrap_incoming(only::StateEvent with EventResult)] pub events: Vec<only::StateEvent>, } /// The private data that this user has attached to this room. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct AccountData { /// A list of events. #[wrap_incoming(only::Event with EventResult)] pub events: Vec<only::Event>, } /// Ephemeral events not recorded in the timeline or state of the room. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct Ephemeral { /// A list of events. #[wrap_incoming(only::Event with EventResult)] pub events: Vec<only::Event>, } /// Updates to the rooms that the user has been invited to. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct InvitedRoom { /// The state of a room that the user has been invited to. #[wrap_incoming] pub invite_state: InviteState, } /// The state of a room that the user has been invited to. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct InviteState { /// A list of state events. #[wrap_incoming(stripped::StrippedState with EventResult)] pub events: Vec<stripped::StrippedState>, } /// Updates to the presence status of other users. #[derive(Clone, Debug, Serialize, Outgoing)] pub struct Presence { /// A list of events. #[wrap_incoming(only::Event with EventResult)] pub events: Vec<only::Event>, }