client-api: Make all pub structs non_exhaustive

This commit is contained in:
Devin Ragotzy 2021-06-18 04:09:19 -07:00 committed by GitHub
parent 626b5a5d06
commit 757ab5273c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 250 additions and 4 deletions

View File

@ -181,6 +181,7 @@ impl fmt::Display for ErrorKind {
/// A Matrix Error without a status code /// A Matrix Error without a status code
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(clippy::exhaustive_structs)]
#[cfg_attr(test, derive(PartialEq))] #[cfg_attr(test, derive(PartialEq))]
pub struct ErrorBody { pub struct ErrorBody {
/// A value which can be used to handle an error message /// A value which can be used to handle an error message
@ -194,6 +195,7 @@ pub struct ErrorBody {
/// A Matrix Error /// A Matrix Error
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(clippy::exhaustive_structs)]
pub struct Error { pub struct Error {
/// A value which can be used to handle an error message /// A value which can be used to handle an error message
pub kind: ErrorKind, pub kind: ErrorKind,

View File

@ -54,7 +54,11 @@ pub enum BackupAlgorithm {
} }
/// Information about the backup key. /// Information about the backup key.
///
/// To create an instance of this type, first create a `KeyBackupDataInit` and convert it via
/// `KeyBackupData::from` / `.into()`.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct KeyBackupData { pub struct KeyBackupData {
/// The index of the first message in the session that the key can decrypt. /// The index of the first message in the session that the key can decrypt.
pub first_message_index: UInt, pub first_message_index: UInt,
@ -69,8 +73,40 @@ pub struct KeyBackupData {
pub session_data: SessionData, pub session_data: SessionData,
} }
/// The algorithm used for storing backups. /// Information about the backup key.
///
/// This struct will not be updated even if additional fields are added to `SessionData` in a
/// new (non-breaking) release of the Matrix specification.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[allow(clippy::exhaustive_structs)]
pub struct KeyBackupDataInit {
/// The index of the first message in the session that the key can decrypt.
pub first_message_index: UInt,
/// The number of times this key has been forwarded via key-sharing between devices.
pub forwarded_count: UInt,
/// Whether the device backing up the key verified the device that the key is from.
pub is_verified: bool,
/// Data about the session.
pub session_data: SessionData,
}
impl From<KeyBackupDataInit> for KeyBackupData {
fn from(init: KeyBackupDataInit) -> Self {
let KeyBackupDataInit { first_message_index, forwarded_count, is_verified, session_data } =
init;
Self { first_message_index, forwarded_count, is_verified, session_data }
}
}
/// The algorithm used for storing backups.
///
/// To create an instance of this type, first create a `SessionDataInit` and convert it via
/// `SessionData::from` / `.into()`.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct SessionData { pub struct SessionData {
/// Unpadded base64-encoded public half of the ephemeral key. /// Unpadded base64-encoded public half of the ephemeral key.
pub ephemeral: String, pub ephemeral: String,
@ -81,3 +117,27 @@ pub struct SessionData {
/// First 8 bytes of MAC key, encoded in base64. /// First 8 bytes of MAC key, encoded in base64.
pub mac: String, pub mac: String,
} }
/// The algorithm used for storing backups.
///
/// This struct will not be updated even if additional fields are added to `SessionData` in a
/// new (non-breaking) release of the Matrix specification.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[allow(clippy::exhaustive_structs)]
pub struct SessionDataInit {
/// Unpadded base64-encoded public half of the ephemeral key.
pub ephemeral: String,
/// Ciphertext, encrypted using AES-CBC-256 with PKCS#7 padding, encoded in base64.
pub ciphertext: String,
/// First 8 bytes of MAC key, encoded in base64.
pub mac: String,
}
impl From<SessionDataInit> for SessionData {
fn from(init: SessionDataInit) -> Self {
let SessionDataInit { ephemeral, ciphertext, mac } = init;
Self { ephemeral, ciphertext, mac }
}
}

View File

@ -76,6 +76,7 @@ pub struct Invite3pid<'a> {
/// This struct will not be updated even if additional fields are added to `Invite3pid` in a new /// This struct will not be updated even if additional fields are added to `Invite3pid` in a new
/// (non-breaking) release of the Matrix specification. /// (non-breaking) release of the Matrix specification.
#[derive(Debug)] #[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct Invite3pidInit<'a> { pub struct Invite3pidInit<'a> {
/// Hostname and port of identity server to be used for account lookups. /// Hostname and port of identity server to be used for account lookups.
pub id_server: &'a str, pub id_server: &'a str,

View File

@ -41,7 +41,11 @@ impl Response {
} }
/// Defines a pusher. /// Defines a pusher.
///
/// To create an instance of this type, first create a `PusherInit` and convert it via
/// `Pusher::from` / `.into()`.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Pusher { pub struct Pusher {
/// This is a unique identifier for this pusher. Max length, 512 bytes. /// This is a unique identifier for this pusher. Max length, 512 bytes.
pub pushkey: String, pub pushkey: String,
@ -68,3 +72,60 @@ pub struct Pusher {
/// Information for the pusher implementation itself. /// Information for the pusher implementation itself.
pub data: PusherData, pub data: PusherData,
} }
/// Initial set of fields of `Pusher`.
///
/// This struct will not be updated even if additional fields are added to `Pusher` in a new
/// (non-breaking) release of the Matrix specification.
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct PusherInit {
/// This is a unique identifier for this pusher. Max length, 512 bytes.
pub pushkey: String,
/// The kind of the pusher. `None` deletes the pusher.
pub kind: PusherKind,
/// This is a reverse-DNS style identifier for the application. Max length, 64 chars.
pub app_id: String,
/// A string that will allow the user to identify what application owns this pusher.
pub app_display_name: String,
/// A string that will allow the user to identify what device owns this pusher.
pub device_display_name: String,
/// This string determines which set of device specific rules this pusher executes.
pub profile_tag: Option<String>,
/// The preferred language for receiving notifications (e.g. 'en' or 'en-US')
pub lang: String,
/// Information for the pusher implementation itself.
pub data: PusherData,
}
impl From<PusherInit> for Pusher {
fn from(init: PusherInit) -> Self {
let PusherInit {
pushkey,
kind,
app_id,
app_display_name,
device_display_name,
profile_tag,
lang,
data,
} = init;
Self {
pushkey,
kind,
app_id,
app_display_name,
device_display_name,
profile_tag,
lang,
data,
}
}
}

View File

@ -48,7 +48,11 @@ impl Response {
} }
/// Defines a pusher. /// Defines a pusher.
///
/// To create an instance of this type, first create a `PusherInit` and convert it via
/// `Pusher::from` / `.into()`.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Pusher { pub struct Pusher {
/// This is a unique identifier for this pusher. Max length, 512 bytes. /// This is a unique identifier for this pusher. Max length, 512 bytes.
pub pushkey: String, pub pushkey: String,
@ -75,3 +79,60 @@ pub struct Pusher {
/// Information for the pusher implementation itself. /// Information for the pusher implementation itself.
pub data: PusherData, pub data: PusherData,
} }
/// Initial set of fields of `Pusher`.
///
/// This struct will not be updated even if additional fields are added to `Pusher` in a new
/// (non-breaking) release of the Matrix specification.
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct PusherInit {
/// This is a unique identifier for this pusher. Max length, 512 bytes.
pub pushkey: String,
/// The kind of the pusher. `None` deletes the pusher.
pub kind: Option<PusherKind>,
/// This is a reverse-DNS style identifier for the application. Max length, 64 chars.
pub app_id: String,
/// A string that will allow the user to identify what application owns this pusher.
pub app_display_name: String,
/// A string that will allow the user to identify what device owns this pusher.
pub device_display_name: String,
/// This string determines which set of device specific rules this pusher executes.
pub profile_tag: Option<String>,
/// The preferred language for receiving notifications (e.g. 'en' or 'en-US')
pub lang: String,
/// Information for the pusher implementation itself.
pub data: PusherData,
}
impl From<PusherInit> for Pusher {
fn from(init: PusherInit) -> Self {
let PusherInit {
pushkey,
kind,
app_id,
app_display_name,
device_display_name,
profile_tag,
lang,
data,
} = init;
Self {
pushkey,
kind,
app_id,
app_display_name,
device_display_name,
profile_tag,
lang,
data,
}
}
}

View File

@ -52,23 +52,40 @@ impl Response {
} }
/// Information about a user's device. /// Information about a user's device.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct DeviceInfo { pub struct DeviceInfo {
/// A list of user sessions on this device. /// A list of user sessions on this device.
#[serde(default, skip_serializing_if = "Vec::is_empty")] #[serde(default, skip_serializing_if = "Vec::is_empty")]
pub sessions: Vec<SessionInfo>, pub sessions: Vec<SessionInfo>,
} }
impl DeviceInfo {
/// Create a new `DeviceInfo` with no sessions.
pub fn new() -> Self {
Self::default()
}
}
/// Information about a user session. /// Information about a user session.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct SessionInfo { pub struct SessionInfo {
/// A list of connections in this session. /// A list of connections in this session.
#[serde(default, skip_serializing_if = "Vec::is_empty")] #[serde(default, skip_serializing_if = "Vec::is_empty")]
pub connections: Vec<ConnectionInfo>, pub connections: Vec<ConnectionInfo>,
} }
impl SessionInfo {
/// Create a new `SessionInfo` with no connections.
pub fn new() -> Self {
Self::default()
}
}
/// Information about a connection in a user session. /// Information about a connection in a user session.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ConnectionInfo { pub struct ConnectionInfo {
/// Most recently seen IP address of the session. /// Most recently seen IP address of the session.
pub ip: Option<String>, pub ip: Option<String>,
@ -79,3 +96,10 @@ pub struct ConnectionInfo {
/// User agent string last seen in the session. /// User agent string last seen in the session.
pub user_agent: Option<String>, pub user_agent: Option<String>,
} }
impl ConnectionInfo {
/// Create a new `ConnectionInfo` with all fields set to `None`.
pub fn new() -> Self {
Self::default()
}
}

View File

@ -240,6 +240,7 @@ pub enum IdentityProviderBrand {
/// A custom login payload. /// A custom login payload.
#[doc(hidden)] #[doc(hidden)]
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[allow(clippy::exhaustive_structs)]
pub struct CustomLoginType { pub struct CustomLoginType {
/// A custom type /// A custom type
/// ///

View File

@ -126,6 +126,7 @@ pub enum LoginInfo<'a> {
/// Client configuration provided by the server. /// Client configuration provided by the server.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct DiscoveryInfo { pub struct DiscoveryInfo {
/// Information about the homeserver to connect to. /// Information about the homeserver to connect to.
#[serde(rename = "m.homeserver")] #[serde(rename = "m.homeserver")]
@ -136,20 +137,43 @@ pub struct DiscoveryInfo {
pub identity_server: Option<IdentityServerInfo>, pub identity_server: Option<IdentityServerInfo>,
} }
impl DiscoveryInfo {
/// Create a new `DiscoveryInfo` with the given homeserver.
pub fn new(homeserver: HomeserverInfo) -> Self {
Self { homeserver, identity_server: None }
}
}
/// Information about the homeserver to connect to. /// Information about the homeserver to connect to.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct HomeserverInfo { pub struct HomeserverInfo {
/// The base URL for the homeserver for client-server connections. /// The base URL for the homeserver for client-server connections.
pub base_url: String, pub base_url: String,
} }
impl HomeserverInfo {
/// Create a new `HomeserverInfo` with the given base url.
pub fn new(base_url: String) -> Self {
Self { base_url }
}
}
/// Information about the identity server to connect to. /// Information about the identity server to connect to.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct IdentityServerInfo { pub struct IdentityServerInfo {
/// The base URL for the identity server for client-server connections. /// The base URL for the identity server for client-server connections.
pub base_url: String, pub base_url: String,
} }
impl IdentityServerInfo {
/// Create a new `IdentityServerInfo` with the given base url.
pub fn new(base_url: String) -> Self {
Self { base_url }
}
}
mod user_serde; mod user_serde;
#[cfg(test)] #[cfg(test)]

View File

@ -1,5 +1,9 @@
//! [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-sync) //! [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-sync)
// FIXME: once https://github.com/rust-lang/rust/issues/84332 is resolved
// the structs can just be non_exhaustive (remove __test_exhaustive)
#![allow(clippy::exhaustive_structs)]
use std::{collections::BTreeMap, time::Duration}; use std::{collections::BTreeMap, time::Duration};
use js_int::UInt; use js_int::UInt;

View File

@ -69,6 +69,7 @@ fn is_default_limit(limit: &UInt) -> bool {
/// User data as result of a search. /// User data as result of a search.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct User { pub struct User {
/// The user's matrix user ID. /// The user's matrix user ID.
pub user_id: UserId, pub user_id: UserId,
@ -88,3 +89,10 @@ pub struct User {
)] )]
pub avatar_url: Option<MxcUri>, pub avatar_url: Option<MxcUri>,
} }
impl User {
/// Create a new `User` with the given `UserId`.
pub fn new(user_id: UserId) -> Self {
Self { user_id, display_name: None, avatar_url: None }
}
}