From 64c5159f04c4ed1e96348b33f9b4c149135f2870 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 19 Aug 2020 02:03:26 +0200 Subject: [PATCH] federation-api: Add lots of non_exhaustive attributes, other minor fixes --- .../r0/directory/get_public_rooms_filtered.rs | 29 +++++++++-- ruma-common/Cargo.toml | 1 + ruma-common/src/directory.rs | 52 +++++++++++-------- .../src/directory/get_public_rooms/v1.rs | 22 +++++++- .../directory/get_public_rooms_filtered/v1.rs | 26 ++++++++-- .../src/discovery/discover_homeserver.rs | 20 ++++++- .../get_remote_server_keys_batch/v2.rs | 10 +++- .../src/discovery/get_server_version/v1.rs | 4 ++ ruma-federation-api/src/keys/claim_keys/v1.rs | 30 ++++++----- ruma-federation-api/src/keys/get_keys/v1.rs | 2 + .../src/membership/create_join_event/v1.rs | 5 +- .../src/membership/create_join_event/v2.rs | 1 + .../create_join_event_template/v1.rs | 13 +++-- .../src/openid/get_openid_userinfo/v1.rs | 2 +- .../src/query/get_room_information/v1.rs | 5 +- .../send_transaction_message/v1.rs | 1 + 16 files changed, 167 insertions(+), 56 deletions(-) diff --git a/ruma-client-api/src/r0/directory/get_public_rooms_filtered.rs b/ruma-client-api/src/r0/directory/get_public_rooms_filtered.rs index 1f597ed9..496ad2d0 100644 --- a/ruma-client-api/src/r0/directory/get_public_rooms_filtered.rs +++ b/ruma-client-api/src/r0/directory/get_public_rooms_filtered.rs @@ -2,7 +2,9 @@ use js_int::UInt; use ruma_api::ruma_api; -use ruma_common::directory::{Filter, PublicRoomsChunk, RoomNetwork}; +use ruma_common::directory::{ + Filter, IncomingFilter, IncomingRoomNetwork, PublicRoomsChunk, RoomNetwork, +}; ruma_api! { metadata: { @@ -14,6 +16,8 @@ ruma_api! { requires_authentication: true, } + #[derive(Default)] + #[non_exhaustive] request: { /// The server to fetch the public room lists from. /// @@ -32,26 +36,45 @@ ruma_api! { /// Filter to apply to the results. #[serde(skip_serializing_if = "Option::is_none")] - pub filter: Option, + pub filter: Option>, /// Network to fetch the public room lists from. #[serde(flatten, skip_serializing_if = "ruma_serde::is_default")] - pub room_network: RoomNetwork, + pub room_network: RoomNetwork<'a>, } + #[derive(Default)] + #[non_exhaustive] response: { /// A paginated chunk of public rooms. pub chunk: Vec, /// A pagination token for the response. + #[serde(skip_serializing_if = "Option::is_none")] pub next_batch: Option, /// A pagination token that allows fetching previous results. + #[serde(skip_serializing_if = "Option::is_none")] pub prev_batch: Option, /// An estimate on the total number of public rooms, if the server has an estimate. + #[serde(skip_serializing_if = "Option::is_none")] pub total_room_count_estimate: Option, } error: crate::Error } + +impl<'a> Request<'a> { + /// Creates an empty `Request`. + pub fn new() -> Self { + Default::default() + } +} + +impl Response { + /// Creates an empty `Response`. + pub fn new() -> Self { + Default::default() + } +} diff --git a/ruma-common/Cargo.toml b/ruma-common/Cargo.toml index 8f5dd9b0..e5eeb085 100644 --- a/ruma-common/Cargo.toml +++ b/ruma-common/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" [dependencies] js_int = { version = "0.1.9", features = ["serde"] } +ruma-api = { version = "=0.17.0-alpha.1", path = "../ruma-api" } ruma-identifiers = { version = "0.17.4", path = "../ruma-identifiers" } ruma-serde = { version = "0.2.3", path = "../ruma-serde" } serde = { version = "1.0.114", features = ["derive"] } diff --git a/ruma-common/src/directory.rs b/ruma-common/src/directory.rs index 85d61028..1468a0a2 100644 --- a/ruma-common/src/directory.rs +++ b/ruma-common/src/directory.rs @@ -3,6 +3,7 @@ use std::fmt; use js_int::UInt; +use ruma_api::Outgoing; use ruma_identifiers::{RoomAliasId, RoomId}; use serde::{ de::{Error, MapAccess, Visitor}, @@ -95,15 +96,15 @@ impl From for PublicRoomsChunk { } /// A filter for public rooms lists -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Outgoing, Serialize)] #[non_exhaustive] -pub struct Filter { +pub struct Filter<'a> { /// A string to search for in the room metadata, e.g. name, topic, canonical alias etc. #[serde(skip_serializing_if = "Option::is_none")] - pub generic_search_term: Option, + pub generic_search_term: Option<&'a str>, } -impl Filter { +impl<'a> Filter<'a> { /// Creates an empty `Filter`. pub fn new() -> Self { Default::default() @@ -112,9 +113,10 @@ impl Filter { /// Information about which networks/protocols from application services on the /// homeserver from which to request rooms. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Outgoing)] #[non_exhaustive] -pub enum RoomNetwork { +#[incoming_derive(Clone, PartialEq, Eq, !Deserialize)] +pub enum RoomNetwork<'a> { /// Return rooms from the Matrix network. Matrix, @@ -122,16 +124,16 @@ pub enum RoomNetwork { All, /// Return rooms from a specific third party network/protocol. - ThirdParty(String), + ThirdParty(&'a str), } -impl Default for RoomNetwork { +impl<'a> Default for RoomNetwork<'a> { fn default() -> Self { RoomNetwork::Matrix } } -impl Serialize for RoomNetwork { +impl<'a> Serialize for RoomNetwork<'a> { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -154,7 +156,7 @@ impl Serialize for RoomNetwork { } } -impl<'de> Deserialize<'de> for RoomNetwork { +impl<'de> Deserialize<'de> for IncomingRoomNetwork { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, @@ -165,7 +167,7 @@ impl<'de> Deserialize<'de> for RoomNetwork { struct RoomNetworkVisitor; impl<'de> Visitor<'de> for RoomNetworkVisitor { - type Value = RoomNetwork; + type Value = IncomingRoomNetwork; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Network selection") @@ -194,7 +196,7 @@ impl<'de> Visitor<'de> for RoomNetworkVisitor { if include_all_networks { if third_party_instance_id.is_none() { - Ok(RoomNetwork::All) + Ok(IncomingRoomNetwork::All) } else { Err(M::Error::custom( "`include_all_networks = true` and `third_party_instance_id` are mutually exclusive.", @@ -202,8 +204,8 @@ impl<'de> Visitor<'de> for RoomNetworkVisitor { } } else { Ok(match third_party_instance_id { - Some(network) => RoomNetwork::ThirdParty(network), - None => RoomNetwork::Matrix, + Some(network) => IncomingRoomNetwork::ThirdParty(network), + None => IncomingRoomNetwork::Matrix, }) } } @@ -213,7 +215,7 @@ impl<'de> Visitor<'de> for RoomNetworkVisitor { mod tests { use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; - use super::RoomNetwork; + use super::{IncomingRoomNetwork, RoomNetwork}; #[test] fn test_serialize_matrix_network_only() { @@ -224,7 +226,10 @@ mod tests { #[test] fn test_deserialize_matrix_network_only() { let json = json!({ "include_all_networks": false }); - assert_eq!(from_json_value::(json).unwrap(), RoomNetwork::Matrix); + assert_eq!( + from_json_value::(json).unwrap(), + IncomingRoomNetwork::Matrix + ); } #[test] @@ -236,7 +241,10 @@ mod tests { #[test] fn test_deserialize_empty_network_is_default() { let json = json!({}); - assert_eq!(from_json_value::(json).unwrap(), RoomNetwork::default()); + assert_eq!( + from_json_value::(json).unwrap(), + IncomingRoomNetwork::Matrix + ); } #[test] @@ -248,21 +256,21 @@ mod tests { #[test] fn test_deserialize_include_all_networks() { let json = json!({ "include_all_networks": true }); - assert_eq!(from_json_value::(json).unwrap(), RoomNetwork::All); + assert_eq!(from_json_value::(json).unwrap(), IncomingRoomNetwork::All); } #[test] fn test_serialize_third_party_network() { let json = json!({ "third_party_instance_id": "freenode" }); - assert_eq!(to_json_value(RoomNetwork::ThirdParty("freenode".into())).unwrap(), json); + assert_eq!(to_json_value(RoomNetwork::ThirdParty("freenode")).unwrap(), json); } #[test] fn test_deserialize_third_party_network() { let json = json!({ "third_party_instance_id": "freenode" }); assert_eq!( - from_json_value::(json).unwrap(), - RoomNetwork::ThirdParty("freenode".into()) + from_json_value::(json).unwrap(), + IncomingRoomNetwork::ThirdParty("freenode".into()) ); } @@ -270,7 +278,7 @@ mod tests { fn test_deserialize_include_all_networks_and_third_party_exclusivity() { let json = json!({ "include_all_networks": true, "third_party_instance_id": "freenode" }); assert_eq!( - from_json_value::(json).unwrap_err().to_string().as_str(), + from_json_value::(json).unwrap_err().to_string().as_str(), "`include_all_networks = true` and `third_party_instance_id` are mutually exclusive." ); } diff --git a/ruma-federation-api/src/directory/get_public_rooms/v1.rs b/ruma-federation-api/src/directory/get_public_rooms/v1.rs index 22ccf173..def43757 100644 --- a/ruma-federation-api/src/directory/get_public_rooms/v1.rs +++ b/ruma-federation-api/src/directory/get_public_rooms/v1.rs @@ -2,7 +2,7 @@ use js_int::UInt; use ruma_api::ruma_api; -use ruma_common::directory::{PublicRoomsChunk, RoomNetwork}; +use ruma_common::directory::{IncomingRoomNetwork, PublicRoomsChunk, RoomNetwork}; ruma_api! { metadata: { @@ -14,6 +14,8 @@ ruma_api! { requires_authentication: true, } + #[derive(Default)] + #[non_exhaustive] request: { /// Limit for the number of results to return. #[serde(skip_serializing_if = "Option::is_none")] @@ -28,9 +30,11 @@ ruma_api! { /// Network to fetch the public room lists from. #[serde(flatten, skip_serializing_if = "ruma_serde::is_default")] #[ruma_api(query)] - pub room_network: RoomNetwork, + pub room_network: RoomNetwork<'a>, } + #[derive(Default)] + #[non_exhaustive] response: { /// A paginated chunk of public rooms. pub chunk: Vec, @@ -47,3 +51,17 @@ ruma_api! { pub total_room_count_estimate: Option, } } + +impl<'a> Request<'a> { + /// Creates an empty `Request`. + pub fn new() -> Self { + Default::default() + } +} + +impl Response { + /// Creates an empty `Response`. + pub fn new() -> Self { + Default::default() + } +} diff --git a/ruma-federation-api/src/directory/get_public_rooms_filtered/v1.rs b/ruma-federation-api/src/directory/get_public_rooms_filtered/v1.rs index 8b2073e6..08fc284c 100644 --- a/ruma-federation-api/src/directory/get_public_rooms_filtered/v1.rs +++ b/ruma-federation-api/src/directory/get_public_rooms_filtered/v1.rs @@ -2,7 +2,9 @@ use js_int::UInt; use ruma_api::ruma_api; -use ruma_common::directory::{Filter, PublicRoomsChunk, RoomNetwork}; +use ruma_common::directory::{ + Filter, IncomingFilter, IncomingRoomNetwork, PublicRoomsChunk, RoomNetwork, +}; ruma_api! { metadata: { @@ -14,6 +16,8 @@ ruma_api! { requires_authentication: true, } + #[derive(Default)] + #[non_exhaustive] request: { /// Limit for the number of results to return. #[serde(skip_serializing_if = "Option::is_none")] @@ -25,13 +29,15 @@ ruma_api! { /// Filter to apply to the results. #[serde(skip_serializing_if = "Option::is_none")] - pub filter: Option, + pub filter: Option>, /// Network to fetch the public room lists from. #[serde(flatten, skip_serializing_if = "ruma_serde::is_default")] - pub room_network: RoomNetwork, + pub room_network: RoomNetwork<'a>, } + #[derive(Default)] + #[non_exhaustive] response: { /// A paginated chunk of public rooms. pub chunk: Vec, @@ -46,3 +52,17 @@ ruma_api! { pub total_room_count_estimate: Option, } } + +impl<'a> Request<'a> { + /// Creates an empty `Request`. + pub fn new() -> Self { + Default::default() + } +} + +impl Response { + /// Creates an empty `Response`. + pub fn new() -> Self { + Default::default() + } +} diff --git a/ruma-federation-api/src/discovery/discover_homeserver.rs b/ruma-federation-api/src/discovery/discover_homeserver.rs index 3c79d57e..23107d74 100644 --- a/ruma-federation-api/src/discovery/discover_homeserver.rs +++ b/ruma-federation-api/src/discovery/discover_homeserver.rs @@ -1,6 +1,7 @@ //! [GET /.well-known/matrix/server](https://matrix.org/docs/spec/server_server/r0.1.3#get-well-known-matrix-server) use ruma_api::ruma_api; +use ruma_identifiers::ServerNameBox; ruma_api! { metadata: { @@ -12,11 +13,28 @@ ruma_api! { requires_authentication: false, } + #[derive(Default)] + #[non_exhaustive] request: {} + #[non_exhaustive] response: { /// The server name to delegate server-server communciations to, with optional port. #[serde(rename = "m.homeserver")] - pub homeserver: String, + pub homeserver: ServerNameBox, + } +} + +impl Request { + /// Creates an empty `Request`. + pub fn new() -> Self { + Self + } +} + +impl Response { + /// Creates a new `Response` with the given homeserver. + pub fn new(homeserver: ServerNameBox) -> Self { + Self { homeserver } } } diff --git a/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs b/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs index 194cc249..4da95082 100644 --- a/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs +++ b/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs @@ -48,7 +48,8 @@ ruma_api! { } /// The query criteria. -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[non_exhaustive] pub struct QueryCriteria { /// A millisecond POSIX timestamp in milliseconds indicating when the /// returned certificates will need to be valid until to be useful to the @@ -63,3 +64,10 @@ pub struct QueryCriteria { )] pub minimum_valid_until_ts: Option, } + +impl QueryCriteria { + /// Creates empty `QueryCriteria`. + pub fn new() -> Self { + Default::default() + } +} diff --git a/ruma-federation-api/src/discovery/get_server_version/v1.rs b/ruma-federation-api/src/discovery/get_server_version/v1.rs index 96f8b529..913eb933 100644 --- a/ruma-federation-api/src/discovery/get_server_version/v1.rs +++ b/ruma-federation-api/src/discovery/get_server_version/v1.rs @@ -13,8 +13,12 @@ ruma_api! { requires_authentication: false, } + #[derive(Default)] + #[non_exhaustive] request: {} + #[derive(Default)] + #[non_exhaustive] response: { /// Information about the homeserver implementation #[serde(skip_serializing_if = "Option::is_none")] diff --git a/ruma-federation-api/src/keys/claim_keys/v1.rs b/ruma-federation-api/src/keys/claim_keys/v1.rs index 55c2246f..28553384 100644 --- a/ruma-federation-api/src/keys/claim_keys/v1.rs +++ b/ruma-federation-api/src/keys/claim_keys/v1.rs @@ -17,17 +17,33 @@ ruma_api! { requires_authentication: true, } + #[non_exhaustive] request: { /// The keys to be claimed. one_time_keys: OneTimeKeyClaims, } + #[non_exhaustive] response: { /// One-time keys for the queried devices one_time_keys: OneTimeKeys, } } +impl Request { + /// Creates a new `Request` with the given one time key claims. + pub fn new(one_time_keys: OneTimeKeyClaims) -> Self { + Self { one_time_keys } + } +} + +impl Response { + /// Creates a new `Response` with the given one time keys. + pub fn new(one_time_keys: OneTimeKeys) -> Self { + Self { one_time_keys } + } +} + /// A claim for one time keys pub type OneTimeKeyClaims = BTreeMap>; @@ -43,17 +59,3 @@ pub struct KeyObject { /// Signature of the key object. signatures: BTreeMap>, } - -impl Request { - /// Creates a new `Request` with the given one time key claims. - pub fn new(one_time_keys: OneTimeKeyClaims) -> Self { - Self { one_time_keys } - } -} - -impl Response { - /// Creates a new `Response` with the given one time keys. - pub fn new(one_time_keys: OneTimeKeys) -> Self { - Self { one_time_keys } - } -} diff --git a/ruma-federation-api/src/keys/get_keys/v1.rs b/ruma-federation-api/src/keys/get_keys/v1.rs index 81e914ca..388cd544 100644 --- a/ruma-federation-api/src/keys/get_keys/v1.rs +++ b/ruma-federation-api/src/keys/get_keys/v1.rs @@ -16,12 +16,14 @@ ruma_api! { requires_authentication: true, } + #[non_exhaustive] request: { /// The keys to be downloaded. Gives all keys for a given user if the list of device ids is /// empty. device_keys: BTreeMap>, } + #[non_exhaustive] response: { /// Keys from the queried devices. device_keys: BTreeMap>, diff --git a/ruma-federation-api/src/membership/create_join_event/v1.rs b/ruma-federation-api/src/membership/create_join_event/v1.rs index 4f3f6c13..64e96667 100644 --- a/ruma-federation-api/src/membership/create_join_event/v1.rs +++ b/ruma-federation-api/src/membership/create_join_event/v1.rs @@ -20,10 +20,11 @@ ruma_api! { request: { /// The room ID that is about to be joined. #[ruma_api(path)] - pub room_id: RoomId, + pub room_id: &'a RoomId, + /// The user ID the join event will be for. #[ruma_api(path)] - pub event_id: EventId, + pub event_id: &'a EventId, /// PDU type without event and room IDs. #[ruma_api(body)] diff --git a/ruma-federation-api/src/membership/create_join_event/v2.rs b/ruma-federation-api/src/membership/create_join_event/v2.rs index dce41437..aecbe8d7 100644 --- a/ruma-federation-api/src/membership/create_join_event/v2.rs +++ b/ruma-federation-api/src/membership/create_join_event/v2.rs @@ -21,6 +21,7 @@ ruma_api! { /// The room ID that is about to be joined. #[ruma_api(path)] pub room_id: RoomId, + /// The user ID the join event will be for. #[ruma_api(path)] pub event_id: EventId, diff --git a/ruma-federation-api/src/membership/create_join_event_template/v1.rs b/ruma-federation-api/src/membership/create_join_event_template/v1.rs index 89832f45..639e5668 100644 --- a/ruma-federation-api/src/membership/create_join_event_template/v1.rs +++ b/ruma-federation-api/src/membership/create_join_event_template/v1.rs @@ -18,19 +18,22 @@ ruma_api! { request: { /// The room ID that is about to be joined. #[ruma_api(path)] - pub room_id: RoomId, + pub room_id: &'a RoomId, + /// The user ID the join event will be for. #[ruma_api(path)] - pub user_id: UserId, - #[ruma_api(query)] + pub user_id: &'a UserId, + /// The room versions the sending server has support for. Defaults to 1. - #[serde(skip_serializing_if = "Vec::is_empty")] - pub ver: Vec, + #[ruma_api(query)] + #[serde(skip_serializing_if = "<[_]>::is_empty")] + pub ver: &'a [RoomVersionId], } response: { /// The version of the room where the server is trying to join. pub room_version: Option, + /// An unsigned template event. pub event: Raw, } diff --git a/ruma-federation-api/src/openid/get_openid_userinfo/v1.rs b/ruma-federation-api/src/openid/get_openid_userinfo/v1.rs index c09102c6..98ea1bac 100644 --- a/ruma-federation-api/src/openid/get_openid_userinfo/v1.rs +++ b/ruma-federation-api/src/openid/get_openid_userinfo/v1.rs @@ -16,7 +16,7 @@ ruma_api! { request: { /// The OpenID access token to get information about the owner for. #[ruma_api(query)] - pub access_token: String, + pub access_token: &'a str, } response: { diff --git a/ruma-federation-api/src/query/get_room_information/v1.rs b/ruma-federation-api/src/query/get_room_information/v1.rs index 2d447a4b..90f4efa8 100644 --- a/ruma-federation-api/src/query/get_room_information/v1.rs +++ b/ruma-federation-api/src/query/get_room_information/v1.rs @@ -1,7 +1,7 @@ //! [GET /_matrix/federation/v1/query/directory](https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-query-directory) use ruma_api::ruma_api; -use ruma_identifiers::RoomId; +use ruma_identifiers::{RoomAliasId, RoomId}; ruma_api! { metadata: { @@ -16,12 +16,13 @@ ruma_api! { request: { /// Room alias to query. #[ruma_api(query)] - pub room_alias: String, + pub room_alias: &'a RoomAliasId, } response: { /// Room ID mapped to queried alias. pub room_id: RoomId, + /// An array of server names that are likely to hold the given room. pub servers: Vec, } diff --git a/ruma-federation-api/src/transactions/send_transaction_message/v1.rs b/ruma-federation-api/src/transactions/send_transaction_message/v1.rs index 41076fdc..38541352 100644 --- a/ruma-federation-api/src/transactions/send_transaction_message/v1.rs +++ b/ruma-federation-api/src/transactions/send_transaction_message/v1.rs @@ -55,6 +55,7 @@ ruma_api! { pub struct Edu { /// Type of the ephemeral message. pub edu_type: String, + /// Content of ephemeral message pub content: JsonValue, }