Borrow things in more endpoint requests

This commit is contained in:
Jonas Platte 2020-08-13 21:22:11 +02:00
parent a00129fcfb
commit b4b96e44fd
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
9 changed files with 81 additions and 81 deletions

View File

@ -16,11 +16,11 @@ ruma_api! {
request: { request: {
/// The media ID from the mxc:// URI (the path component). /// The media ID from the mxc:// URI (the path component).
#[ruma_api(path)] #[ruma_api(path)]
pub media_id: String, pub media_id: &'a str,
/// The server name from the mxc:// URI (the authoritory component). /// The server name from the mxc:// URI (the authoritory component).
#[ruma_api(path)] #[ruma_api(path)]
pub server_name: Box<ServerName>, pub server_name: &'a ServerName,
/// Whether to fetch media deemed remote. /// Whether to fetch media deemed remote.
/// Used to prevent routing loops. Defaults to `true`. /// Used to prevent routing loops. Defaults to `true`.

View File

@ -16,15 +16,15 @@ ruma_api! {
request: { request: {
/// The media ID from the mxc:// URI (the path component). /// The media ID from the mxc:// URI (the path component).
#[ruma_api(path)] #[ruma_api(path)]
pub media_id: String, pub media_id: &'a str,
/// The server name from the mxc:// URI (the authoritory component). /// The server name from the mxc:// URI (the authoritory component).
#[ruma_api(path)] #[ruma_api(path)]
pub server_name: Box<ServerName>, pub server_name: &'a ServerName,
/// The filename to return in the `Content-Disposition` header. /// The filename to return in the `Content-Disposition` header.
#[ruma_api(path)] #[ruma_api(path)]
pub filename: String, pub filename: &'a str,
/// Whether to fetch media deemed remote. /// Whether to fetch media deemed remote.
/// Used to prevent routing loops. Defaults to `true`. /// Used to prevent routing loops. Defaults to `true`.

View File

@ -36,11 +36,11 @@ ruma_api! {
/// The media ID from the mxc:// URI (the path component). /// The media ID from the mxc:// URI (the path component).
#[ruma_api(path)] #[ruma_api(path)]
pub media_id: String, pub media_id: &'a str,
/// The server name from the mxc:// URI (the authoritory component). /// The server name from the mxc:// URI (the authoritory component).
#[ruma_api(path)] #[ruma_api(path)]
pub server_name: Box<ServerName>, pub server_name: &'a ServerName,
/// The *desired* height of the thumbnail. The actual thumbnail may not match the size /// The *desired* height of the thumbnail. The actual thumbnail may not match the size
/// specified. /// specified.

View File

@ -1,8 +1,8 @@
//! [POST /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login) //! [POST /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login)
use ruma_api::ruma_api; use ruma_api::{ruma_api, Outgoing};
use ruma_common::thirdparty::Medium; use ruma_common::thirdparty::Medium;
use ruma_identifiers::{DeviceIdBox, ServerName, UserId}; use ruma_identifiers::{DeviceId, DeviceIdBox, ServerName, UserId};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
ruma_api! { ruma_api! {
@ -18,20 +18,20 @@ ruma_api! {
request: { request: {
/// Identification information for the user. /// Identification information for the user.
#[serde(flatten)] #[serde(flatten)]
pub user: UserInfo, pub user: UserInfo<'a>,
/// The authentication mechanism. /// The authentication mechanism.
#[serde(flatten)] #[serde(flatten)]
pub login_info: LoginInfo, pub login_info: LoginInfo<'a>,
/// ID of the client device /// ID of the client device
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub device_id: Option<DeviceIdBox>, pub device_id: Option<&'a DeviceId>,
/// A display name to assign to the newly-created device. Ignored if device_id corresponds /// A display name to assign to the newly-created device. Ignored if device_id corresponds
/// to a known device. /// to a known device.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub initial_device_display_name: Option<String>, pub initial_device_display_name: Option<&'a str>,
} }
response: { response: {
@ -64,17 +64,17 @@ ruma_api! {
} }
/// Identification information for the user. /// Identification information for the user.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Outgoing, Serialize)]
#[serde(from = "user_serde::UserInfo", into = "user_serde::UserInfo")] #[serde(from = "user_serde::IncomingUserInfo", into = "user_serde::UserInfo")]
pub enum UserInfo { pub enum UserInfo<'a> {
/// Either a fully qualified Matrix user ID, or just the localpart (as part of the 'identifier' /// Either a fully qualified Matrix user ID, or just the localpart (as part of the 'identifier'
/// field). /// field).
MatrixId(String), MatrixId(&'a str),
/// Third party identifier (as part of the 'identifier' field). /// Third party identifier (as part of the 'identifier' field).
ThirdPartyId { ThirdPartyId {
/// Third party identifier for the user. /// Third party identifier for the user.
address: String, address: &'a str,
/// The medium of the identifier. /// The medium of the identifier.
medium: Medium, medium: Medium,
@ -84,29 +84,29 @@ pub enum UserInfo {
/// phone number. /// phone number.
PhoneNumber { PhoneNumber {
/// The country that the phone number is from. /// The country that the phone number is from.
country: String, country: &'a str,
/// The phone number. /// The phone number.
phone: String, phone: &'a str,
}, },
} }
/// The authentication mechanism. /// The authentication mechanism.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Outgoing, Serialize)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum LoginInfo { pub enum LoginInfo<'a> {
/// A password is supplied to authenticate. /// A password is supplied to authenticate.
#[serde(rename = "m.login.password")] #[serde(rename = "m.login.password")]
Password { Password {
/// The password. /// The password.
password: String, password: &'a str,
}, },
/// Token-based login. /// Token-based login.
#[serde(rename = "m.login.token")] #[serde(rename = "m.login.token")]
Token { Token {
/// The token. /// The token.
token: String, token: &'a str,
}, },
} }
@ -140,56 +140,57 @@ mod user_serde;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use matches::assert_matches;
use ruma_api::OutgoingRequest; use ruma_api::OutgoingRequest;
use serde_json::{from_value as from_json_value, json, Value as JsonValue}; use serde_json::{from_value as from_json_value, json, Value as JsonValue};
use super::{LoginInfo, Medium, Request, UserInfo}; use super::{IncomingLoginInfo, IncomingUserInfo, LoginInfo, Medium, Request, UserInfo};
#[test] #[test]
fn deserialize_login_type() { fn deserialize_login_type() {
assert_eq!( assert_matches!(
from_json_value::<LoginInfo>(json!({ from_json_value(json!({
"type": "m.login.password", "type": "m.login.password",
"password": "ilovebananas" "password": "ilovebananas"
})) }))
.unwrap(), .unwrap(),
LoginInfo::Password { password: "ilovebananas".into() } IncomingLoginInfo::Password { password }
if password == "ilovebananas"
); );
assert_eq!( assert_matches!(
from_json_value::<LoginInfo>(json!({ from_json_value(json!({
"type": "m.login.token", "type": "m.login.token",
"token": "1234567890abcdef" "token": "1234567890abcdef"
})) }))
.unwrap(), .unwrap(),
LoginInfo::Token { token: "1234567890abcdef".into() } IncomingLoginInfo::Token { token }
if token == "1234567890abcdef"
); );
} }
#[test] #[test]
fn deserialize_user() { fn deserialize_user() {
assert_eq!( assert_matches!(
from_json_value::<UserInfo>(json!({ from_json_value(json!({
"identifier": { "identifier": {
"type": "m.id.user", "type": "m.id.user",
"user": "cheeky_monkey" "user": "cheeky_monkey"
} }
})) }))
.unwrap(), .unwrap(),
UserInfo::MatrixId("cheeky_monkey".into()) IncomingUserInfo::MatrixId(id)
if id == "cheeky_monkey"
); );
} }
#[test] #[test]
fn serialize_login_request_body() { fn serialize_login_request_body() {
let req: http::Request<Vec<u8>> = Request { let req: http::Request<Vec<u8>> = Request {
user: UserInfo::ThirdPartyId { user: UserInfo::ThirdPartyId { address: "hello@example.com", medium: Medium::Email },
address: "hello@example.com".to_owned(), login_info: LoginInfo::Token { token: "0xdeadbeef" },
medium: Medium::Email,
},
login_info: LoginInfo::Token { token: "0xdeadbeef".to_owned() },
device_id: None, device_id: None,
initial_device_display_name: Some("test".into()), initial_device_display_name: Some("test"),
} }
.try_into_http_request("https://homeserver.tld", None) .try_into_http_request("https://homeserver.tld", None)
.unwrap(); .unwrap();

View File

@ -1,51 +1,54 @@
//! Helper module for the Serialize / Deserialize impl's for the User struct //! Helper module for the Serialize / Deserialize impl's for the User struct
//! in the parent module. //! in the parent module.
use ruma_api::Outgoing;
use ruma_common::thirdparty::Medium; use ruma_common::thirdparty::Medium;
use serde::{Deserialize, Serialize}; use serde::Serialize;
// The following three structs could just be used in place of the one in the parent module, but // The following three structs could just be used in place of the one in the parent module, but
// that one is arguably much easier to deal with. // that one is arguably much easier to deal with.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Outgoing, Serialize)]
pub(crate) struct UserInfo { pub(crate) struct UserInfo<'a> {
pub identifier: UserIdentifier, pub identifier: UserIdentifier<'a>,
} }
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Outgoing, Serialize)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub(crate) enum UserIdentifier { pub(crate) enum UserIdentifier<'a> {
#[serde(rename = "m.id.user")] #[serde(rename = "m.id.user")]
MatrixId { user: String }, MatrixId { user: &'a str },
#[serde(rename = "m.id.thirdparty")] #[serde(rename = "m.id.thirdparty")]
ThirdPartyId { medium: Medium, address: String }, ThirdPartyId { medium: Medium, address: &'a str },
#[serde(rename = "m.id.phone")] #[serde(rename = "m.id.phone")]
PhoneNumber { country: String, phone: String }, PhoneNumber { country: &'a str, phone: &'a str },
} }
impl From<super::UserInfo> for UserInfo { impl<'a> From<super::UserInfo<'a>> for UserInfo<'a> {
fn from(info: super::UserInfo) -> Self { fn from(info: super::UserInfo<'a>) -> Self {
use super::UserInfo::*; use super::UserInfo as Info;
use UserIdentifier as Id;
match info { match info {
MatrixId(user) => UserInfo { identifier: UserIdentifier::MatrixId { user } }, Info::MatrixId(user) => UserInfo { identifier: Id::MatrixId { user } },
ThirdPartyId { address, medium } => { Info::ThirdPartyId { address, medium } => {
UserInfo { identifier: UserIdentifier::ThirdPartyId { address, medium } } UserInfo { identifier: Id::ThirdPartyId { address, medium } }
} }
PhoneNumber { country, phone } => { Info::PhoneNumber { country, phone } => {
UserInfo { identifier: UserIdentifier::PhoneNumber { country, phone } } UserInfo { identifier: Id::PhoneNumber { country, phone } }
} }
} }
} }
} }
impl From<UserInfo> for super::UserInfo { impl From<IncomingUserInfo> for super::IncomingUserInfo {
fn from(info: UserInfo) -> super::UserInfo { fn from(info: IncomingUserInfo) -> super::IncomingUserInfo {
use super::UserInfo::*; use super::IncomingUserInfo as Info;
use IncomingUserIdentifier as Id;
match info.identifier { match info.identifier {
UserIdentifier::MatrixId { user } => MatrixId(user), Id::MatrixId { user } => Info::MatrixId(user),
UserIdentifier::ThirdPartyId { address, medium } => ThirdPartyId { address, medium }, Id::ThirdPartyId { address, medium } => Info::ThirdPartyId { address, medium },
UserIdentifier::PhoneNumber { country, phone } => PhoneNumber { country, phone }, Id::PhoneNumber { country, phone } => Info::PhoneNumber { country, phone },
} }
} }
} }

View File

@ -11,11 +11,7 @@ use ruma::{
}; };
use ruma_client::{self, HttpClient}; use ruma_client::{self, HttpClient};
async fn log_messages( async fn log_messages(homeserver_url: Uri, username: &str, password: &str) -> anyhow::Result<()> {
homeserver_url: Uri,
username: String,
password: String,
) -> anyhow::Result<()> {
let client = HttpClient::new(homeserver_url, None); let client = HttpClient::new(homeserver_url, None);
client.log_in(username, password, None, None).await?; client.log_in(username, password, None, None).await?;
@ -68,5 +64,5 @@ async fn main() -> anyhow::Result<()> {
}; };
let server = homeserver_url.parse()?; let server = homeserver_url.parse()?;
log_messages(server, username, password).await log_messages(server, &username, &password).await
} }

View File

@ -13,7 +13,7 @@
//! let client = Client::https(homeserver_url, None); //! let client = Client::https(homeserver_url, None);
//! //!
//! let session = client //! let session = client
//! .log_in("@alice:example.com".to_string(), "secret".to_string(), None, None) //! .log_in("@alice:example.com", "secret", None, None)
//! .await?; //! .await?;
//! //!
//! // You're now logged in! Write the session to a file if you want to restore it later. //! // You're now logged in! Write the session to a file if you want to restore it later.
@ -117,7 +117,7 @@ use ruma_api::OutgoingRequest;
use ruma_client_api::r0::sync::sync_events::{ use ruma_client_api::r0::sync::sync_events::{
Filter as SyncFilter, Request as SyncRequest, Response as SyncResponse, Filter as SyncFilter, Request as SyncRequest, Response as SyncResponse,
}; };
use ruma_identifiers::DeviceIdBox; use ruma_identifiers::DeviceId;
use ruma_serde::urlencoded; use ruma_serde::urlencoded;
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -209,10 +209,10 @@ where
/// returning it. /// returning it.
pub async fn log_in( pub async fn log_in(
&self, &self,
user: String, user: &str,
password: String, password: &str,
device_id: Option<DeviceIdBox>, device_id: Option<&DeviceId>,
initial_device_display_name: Option<String>, initial_device_display_name: Option<&str>,
) -> Result<Session, Error<ruma_client_api::Error>> { ) -> Result<Session, Error<ruma_client_api::Error>> {
use ruma_client_api::r0::session::login; use ruma_client_api::r0::session::login;

View File

@ -19,7 +19,7 @@ ruma_api! {
request: { request: {
/// The server's DNS name to query /// The server's DNS name to query
#[ruma_api(path)] #[ruma_api(path)]
pub server_name: Box<ServerName>, pub server_name: &'a ServerName,
/// A millisecond POSIX timestamp in milliseconds indicating when the /// A millisecond POSIX timestamp in milliseconds indicating when the
/// returned certificates will need to be valid until to be useful to /// returned certificates will need to be valid until to be useful to

View File

@ -21,10 +21,10 @@ ruma_api! {
request: { request: {
/// A transaction ID unique between sending and receiving homeservers. /// A transaction ID unique between sending and receiving homeservers.
#[ruma_api(path)] #[ruma_api(path)]
pub transaction_id: String, pub transaction_id: &'a str,
/// The server_name of the homeserver sending this transaction. /// The server_name of the homeserver sending this transaction.
pub origin: Box<ServerName>, pub origin: &'a ServerName,
/// POSIX timestamp in milliseconds on the originating homeserver when this transaction /// POSIX timestamp in milliseconds on the originating homeserver when this transaction
/// started. /// started.
@ -34,13 +34,13 @@ ruma_api! {
/// List of persistent updates to rooms. /// List of persistent updates to rooms.
/// ///
/// Must not be more than 50 items. /// Must not be more than 50 items.
pub pdus: Vec<Pdu>, pub pdus: &'a [Pdu],
/// List of ephemeral messages. /// List of ephemeral messages.
/// ///
/// Must not be more than 100 items. /// Must not be more than 100 items.
#[serde(skip_serializing_if = "Vec::is_empty")] #[serde(skip_serializing_if = "<[_]>::is_empty")]
pub edus: Vec<Edu>, pub edus: &'a [Edu],
} }
response: { response: {