From e4cd59e7e5f8ce4c8b90948155c3d031e45f9c54 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 26 Aug 2020 11:30:39 +0200 Subject: [PATCH] client-api: Various API updates --- ruma-client-api/src/r0/account/register.rs | 31 +++++++++-- ruma-client-api/src/r0/membership.rs | 13 ++--- .../src/r0/membership/invite_user.rs | 54 +++++++++++++------ .../r0/membership/join_room_by_id_or_alias.rs | 20 ++++++- .../src/r0/message/get_message_events.rs | 12 ++++- .../src/r0/read_marker/set_read_marker.rs | 23 ++++++-- ruma-client-api/src/r0/room/create_room.rs | 4 +- ruma-client/src/lib.rs | 22 ++------ 8 files changed, 125 insertions(+), 54 deletions(-) diff --git a/ruma-client-api/src/r0/account/register.rs b/ruma-client-api/src/r0/account/register.rs index 7f21d41b..38315bca 100644 --- a/ruma-client-api/src/r0/account/register.rs +++ b/ruma-client-api/src/r0/account/register.rs @@ -16,6 +16,8 @@ ruma_api! { requires_authentication: false, } + #[derive(Default)] + #[non_exhaustive] request: { /// The desired password for the account. /// @@ -24,7 +26,7 @@ ruma_api! { #[serde(skip_serializing_if = "Option::is_none")] pub password: Option<&'a str>, - /// local part of the desired Matrix ID. + /// Localpart of the desired Matrix ID. /// /// If omitted, the homeserver MUST generate a Matrix ID local part. #[serde(skip_serializing_if = "Option::is_none")] @@ -56,8 +58,8 @@ ruma_api! { /// /// Defaults to `User` if omitted. #[ruma_api(query)] - #[serde(skip_serializing_if = "Option::is_none")] - pub kind: Option, + #[serde(default, skip_serializing_if = "ruma_serde::is_default")] + pub kind: RegistrationKind, /// If `true`, an `access_token` and `device_id` should not be returned /// from this call, therefore preventing an automatic login. @@ -65,6 +67,7 @@ ruma_api! { pub inhibit_login: bool, } + #[non_exhaustive] response: { /// An access token for the account. /// @@ -84,8 +87,22 @@ ruma_api! { error: UiaaResponse } +impl<'a> Request<'a> { + /// Creates a new `Request` with all parameters defaulted. + pub fn new() -> Self { + Default::default() + } +} + +impl Response { + /// Creates a new `Response` with the given user ID. + pub fn new(user_id: UserId) -> Self { + Self { access_token: None, user_id, device_id: None } + } +} + /// The kind of account being registered. -#[derive(Copy, Clone, Debug, Deserialize, Serialize)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum RegistrationKind { /// A guest account @@ -96,3 +113,9 @@ pub enum RegistrationKind { /// A regular user account User, } + +impl Default for RegistrationKind { + fn default() -> Self { + Self::User + } +} diff --git a/ruma-client-api/src/r0/membership.rs b/ruma-client-api/src/r0/membership.rs index 38162327..bb2b68da 100644 --- a/ruma-client-api/src/r0/membership.rs +++ b/ruma-client-api/src/r0/membership.rs @@ -17,7 +17,7 @@ use std::collections::BTreeMap; use ruma_api::Outgoing; use ruma_common::thirdparty::Medium; use ruma_identifiers::{ServerKeyId, ServerNameBox}; -use serde::{Deserialize, Serialize}; +use serde::Serialize; /// A signature of an `m.third_party_invite` token to prove that this user owns a third party /// identity which has been invited to the room. @@ -37,17 +37,18 @@ pub struct ThirdPartySigned<'a> { } /// Represents third party IDs to invite to the room. -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] -pub struct Invite3pid { +#[derive(Clone, Debug, PartialEq, Outgoing, Serialize)] +#[incoming_derive(PartialEq)] +pub struct Invite3pid<'a> { /// Hostname and port of identity server to be used for account lookups. - pub id_server: String, + pub id_server: &'a str, /// An access token registered with the identity server. - pub id_access_token: String, + pub id_access_token: &'a str, /// Type of third party ID. pub medium: Medium, /// Third party identifier. - pub address: String, + pub address: &'a str, } diff --git a/ruma-client-api/src/r0/membership/invite_user.rs b/ruma-client-api/src/r0/membership/invite_user.rs index 102a8f71..6396e52f 100644 --- a/ruma-client-api/src/r0/membership/invite_user.rs +++ b/ruma-client-api/src/r0/membership/invite_user.rs @@ -7,11 +7,11 @@ //! [invite-by-user-id]: https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-invite //! [invite-by-3pid]: https://matrix.org/docs/spec/client_server/r0.6.0#id101 -use ruma_api::ruma_api; +use ruma_api::{ruma_api, Outgoing}; use ruma_identifiers::{RoomId, UserId}; -use serde::{Deserialize, Serialize}; +use serde::Serialize; -use super::Invite3pid; +use super::{IncomingInvite3pid, Invite3pid}; ruma_api! { metadata: { @@ -23,33 +23,52 @@ ruma_api! { requires_authentication: true, } + #[non_exhaustive] request: { /// The room where the user should be invited. #[ruma_api(path)] - pub room_id: RoomId, + pub room_id: &'a RoomId, /// The user to invite. #[ruma_api(body)] - pub recipient: InvitationRecipient, + pub recipient: InvitationRecipient<'a>, } + #[derive(Default)] + #[non_exhaustive] response: {} error: crate::Error } +impl<'a> Request<'a> { + /// Creates a new `Request` with the given room ID and invitation recipient. + pub fn new(room_id: &'a RoomId, recipient: InvitationRecipient<'a>) -> Self { + Self { room_id, recipient } + } +} + +impl Response { + /// Creates an empty `Response`. + pub fn new() -> Self { + Self + } +} + /// Distinguishes between invititations by Matrix or third party identifiers. -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Outgoing, Serialize)] +#[non_exhaustive] +#[incoming_derive(PartialEq)] #[serde(untagged)] -pub enum InvitationRecipient { +pub enum InvitationRecipient<'a> { /// Used to invite user by their Matrix identifer. UserId { /// Matrix identifier of user. - user_id: UserId, + user_id: &'a UserId, }, /// Used to invite user by a third party identifer. - ThirdPartyId(Invite3pid), + ThirdPartyId(Invite3pid<'a>), } #[cfg(test)] @@ -58,29 +77,30 @@ mod tests { use ruma_identifiers::user_id; use serde_json::{from_value as from_json_value, json}; - use super::InvitationRecipient; - use crate::r0::membership::Invite3pid; + use super::IncomingInvitationRecipient; + use crate::r0::membership::IncomingInvite3pid; #[test] fn deserialize_invite_by_user_id() { - let incoming = - from_json_value::(json!({ "user_id": "@carl:example.org" })) - .unwrap(); + let incoming = from_json_value::( + json!({ "user_id": "@carl:example.org" }), + ) + .unwrap(); let user_id = user_id!("@carl:example.org"); - let recipient = InvitationRecipient::UserId { user_id }; + let recipient = IncomingInvitationRecipient::UserId { user_id }; assert_eq!(incoming, recipient); } #[test] fn deserialize_invite_by_3pid() { - let incoming = from_json_value::(json!({ + let incoming = from_json_value::(json!({ "id_server": "example.org", "id_access_token": "abcdefghijklmnop", "medium": "email", "address": "carl@example.org" })) .unwrap(); - let recipient = InvitationRecipient::ThirdPartyId(Invite3pid { + let recipient = IncomingInvitationRecipient::ThirdPartyId(IncomingInvite3pid { id_server: "example.org".into(), id_access_token: "abcdefghijklmnop".into(), medium: Medium::Email, diff --git a/ruma-client-api/src/r0/membership/join_room_by_id_or_alias.rs b/ruma-client-api/src/r0/membership/join_room_by_id_or_alias.rs index bfb69791..39a27a8d 100644 --- a/ruma-client-api/src/r0/membership/join_room_by_id_or_alias.rs +++ b/ruma-client-api/src/r0/membership/join_room_by_id_or_alias.rs @@ -15,15 +15,16 @@ ruma_api! { requires_authentication: true, } + #[non_exhaustive] request: { /// The room where the user should be invited. #[ruma_api(path)] - pub room_id_or_alias: RoomIdOrAliasId, + pub room_id_or_alias: &'a RoomIdOrAliasId, /// The servers to attempt to join the room through. One of the servers /// must be participating in the room. #[ruma_api(query)] - #[serde(default)] + #[serde(default, skip_serializing_if = "<[_]>::is_empty")] pub server_name: &'a [ServerNameBox], /// The signature of a `m.third_party_invite` token to prove that this user owns a third @@ -32,6 +33,7 @@ ruma_api! { pub third_party_signed: Option>, } + #[non_exhaustive] response: { /// The room that the user joined. pub room_id: RoomId, @@ -39,3 +41,17 @@ ruma_api! { error: crate::Error } + +impl<'a> Request<'a> { + /// Creates a new `Request` with the given room ID or alias ID. + pub fn new(room_id_or_alias: &'a RoomIdOrAliasId) -> Self { + Self { room_id_or_alias, server_name: &[], third_party_signed: None } + } +} + +impl Response { + /// Creates a new `Response` with the given room ID. + pub fn new(room_id: RoomId) -> Self { + Self { room_id } + } +} diff --git a/ruma-client-api/src/r0/message/get_message_events.rs b/ruma-client-api/src/r0/message/get_message_events.rs index a189b3c3..9a1415cc 100644 --- a/ruma-client-api/src/r0/message/get_message_events.rs +++ b/ruma-client-api/src/r0/message/get_message_events.rs @@ -87,12 +87,22 @@ ruma_api! { } impl<'a> Request<'a> { - /// Creates a `Request` with the given parameters. + /// Creates a new `Request` with the given parameters. /// /// All other parameters will be defaulted. pub fn new(room_id: &'a RoomId, from: &'a str, dir: Direction) -> Self { Self { room_id, from, to: None, dir, limit: default_limit(), filter: None } } + + /// Creates a new `Request` with the given room ID and from token, and `dir` set to `Backward`. + pub fn backward(room_id: &'a RoomId, from: &'a str) -> Self { + Self::new(room_id, from, Direction::Backward) + } + + /// Creates a new `Request` with the given room ID and from token, and `dir` set to `Forward`. + pub fn forward(room_id: &'a RoomId, from: &'a str) -> Self { + Self::new(room_id, from, Direction::Forward) + } } impl Response { diff --git a/ruma-client-api/src/r0/read_marker/set_read_marker.rs b/ruma-client-api/src/r0/read_marker/set_read_marker.rs index b9de5182..d75e3877 100644 --- a/ruma-client-api/src/r0/read_marker/set_read_marker.rs +++ b/ruma-client-api/src/r0/read_marker/set_read_marker.rs @@ -13,25 +13,42 @@ ruma_api! { requires_authentication: true, } + #[non_exhaustive] request: { /// The room ID to set the read marker in for the user. #[ruma_api(path)] - pub room_id: RoomId, + pub room_id: &'a RoomId, /// The event ID the read marker should be located at. /// The event MUST belong to the room. #[serde(rename = "m.fully_read")] - pub fully_read: EventId, + pub fully_read: &'a EventId, /// The event ID to set the read receipt location at. /// This is equivalent to calling the create_read_receipt endpoint and is /// provided here to save that extra call. #[serde(rename = "m.read", skip_serializing_if = "Option::is_none")] - pub read_receipt: Option, + pub read_receipt: Option<&'a EventId>, } + #[derive(Default)] + #[non_exhaustive] response: {} error: crate::Error } + +impl<'a> Request<'a> { + /// Creates a new `Request` with the given room ID and fully read event ID. + pub fn new(room_id: &'a RoomId, fully_read: &'a EventId) -> Self { + Self { room_id, fully_read, read_receipt: None } + } +} + +impl Response { + /// Creates an empty `Response`. + pub fn new() -> Self { + Self + } +} diff --git a/ruma-client-api/src/r0/room/create_room.rs b/ruma-client-api/src/r0/room/create_room.rs index 5c09a6af..6f91c5f7 100644 --- a/ruma-client-api/src/r0/room/create_room.rs +++ b/ruma-client-api/src/r0/room/create_room.rs @@ -14,7 +14,7 @@ use ruma_identifiers::{RoomId, RoomVersionId, UserId}; use serde::{Deserialize, Serialize}; use super::Visibility; -use crate::r0::membership::Invite3pid; +use crate::r0::membership::{IncomingInvite3pid, Invite3pid}; ruma_api! { metadata: { @@ -48,7 +48,7 @@ ruma_api! { /// List of third party IDs of users to invite. #[serde(default, skip_serializing_if = "<[_]>::is_empty")] - pub invite_3pid: &'a [Invite3pid], + pub invite_3pid: &'a [Invite3pid<'a>], /// If set, this sets the `is_direct` flag on room invites. #[serde(default, skip_serializing_if = "ruma_serde::is_default")] diff --git a/ruma-client/src/lib.rs b/ruma-client/src/lib.rs index 05a7e046..f086e3e7 100644 --- a/ruma-client/src/lib.rs +++ b/ruma-client/src/lib.rs @@ -243,18 +243,10 @@ where pub async fn register_guest( &self, ) -> Result> { - use ruma_client_api::r0::account::register; + use ruma_client_api::r0::account::register::{self, RegistrationKind}; let response = self - .request(register::Request { - auth: None, - device_id: None, - inhibit_login: false, - initial_device_display_name: None, - kind: Some(register::RegistrationKind::Guest), - password: None, - username: None, - }) + .request(assign!(register::Request::new(), { kind: RegistrationKind::Guest })) .await?; let session = Session { @@ -288,15 +280,7 @@ where use ruma_client_api::r0::account::register; let response = self - .request(register::Request { - auth: None, - device_id: None, - inhibit_login: false, - initial_device_display_name: None, - kind: Some(register::RegistrationKind::User), - password: Some(password), - username, - }) + .request(assign!(register::Request::new(), { username, password: Some(password) })) .await?; let session = Session {