client-api: More borrowing
This commit is contained in:
parent
7557ed438b
commit
d6c15e5769
@ -18,14 +18,15 @@ ruma_api! {
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
request: {
|
||||
/// The room to get events from.
|
||||
#[ruma_api(path)]
|
||||
pub room_id: RoomId,
|
||||
pub room_id: &'a RoomId,
|
||||
|
||||
/// The event to get context around.
|
||||
#[ruma_api(path)]
|
||||
pub event_id: EventId,
|
||||
pub event_id: &'a EventId,
|
||||
|
||||
/// The maximum number of events to return.
|
||||
///
|
||||
@ -44,6 +45,7 @@ ruma_api! {
|
||||
pub filter: Option<RoomEventFilter>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
response: {
|
||||
/// A token that can be used to paginate backwards with.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@ -75,6 +77,27 @@ ruma_api! {
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
impl<'a> Request<'a> {
|
||||
/// Creates a new `Request` with the given room id and event id.
|
||||
pub fn new(room_id: &'a RoomId, event_id: &'a EventId) -> Self {
|
||||
Self { room_id, event_id, limit: default_limit(), filter: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates an empty `Response`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
start: None,
|
||||
end: None,
|
||||
events_before: Vec::new(),
|
||||
event: None,
|
||||
events_after: Vec::new(),
|
||||
state: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_limit() -> UInt {
|
||||
uint!(10)
|
||||
}
|
||||
|
@ -15,18 +15,20 @@ ruma_api! {
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
request: {
|
||||
/// The ID of the user uploading the filter.
|
||||
///
|
||||
/// The access token must be authorized to make requests for this user ID.
|
||||
#[ruma_api(path)]
|
||||
pub user_id: UserId,
|
||||
pub user_id: &'a UserId,
|
||||
|
||||
/// The filter definition.
|
||||
#[ruma_api(body)]
|
||||
pub filter: FilterDefinition,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
response: {
|
||||
/// The ID of the filter that was created.
|
||||
pub filter_id: String,
|
||||
@ -34,3 +36,17 @@ ruma_api! {
|
||||
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
impl<'a> Request<'a> {
|
||||
/// Creates a new `Request` with the given user ID and filter definition.
|
||||
pub fn new(user_id: &'a UserId, filter: FilterDefinition) -> Self {
|
||||
Self { user_id, filter }
|
||||
}
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates a new `Response` with the given filter ID.
|
||||
pub fn new(filter_id: String) -> Self {
|
||||
Self { filter_id }
|
||||
}
|
||||
}
|
||||
|
@ -15,16 +15,18 @@ ruma_api! {
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
request: {
|
||||
/// The user ID to download a filter for.
|
||||
#[ruma_api(path)]
|
||||
pub user_id: UserId,
|
||||
pub user_id: &'a UserId,
|
||||
|
||||
/// The ID of the filter to download.
|
||||
#[ruma_api(path)]
|
||||
pub filter_id: String,
|
||||
pub filter_id: &'a str,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
response: {
|
||||
/// The filter definition.
|
||||
#[ruma_api(body)]
|
||||
@ -33,3 +35,17 @@ ruma_api! {
|
||||
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
impl<'a> Request<'a> {
|
||||
/// Creates a new `Request` with the given user ID and filter ID.
|
||||
pub fn new(user_id: &'a UserId, filter_id: &'a str) -> Self {
|
||||
Self { user_id, filter_id }
|
||||
}
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates a new `Response` with the given filter definition.
|
||||
pub fn new(filter: FilterDefinition) -> Self {
|
||||
Self { filter }
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ ruma_api! {
|
||||
request: {
|
||||
/// The room to get events from.
|
||||
#[ruma_api(path)]
|
||||
pub room_id: RoomId,
|
||||
pub room_id: &'a RoomId,
|
||||
|
||||
/// The token to start returning events from.
|
||||
///
|
||||
@ -31,7 +31,7 @@ ruma_api! {
|
||||
/// prev_batch token returned for each room by the sync API, or from a start or end token
|
||||
/// returned by a previous request to this endpoint.
|
||||
#[ruma_api(query)]
|
||||
pub from: String,
|
||||
pub from: &'a str,
|
||||
|
||||
/// The token to stop returning events at.
|
||||
///
|
||||
@ -40,7 +40,7 @@ ruma_api! {
|
||||
/// by a previous request to this endpoint.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[ruma_api(query)]
|
||||
pub to: Option<String>,
|
||||
pub to: Option<&'a str>,
|
||||
|
||||
/// The direction to return events from.
|
||||
#[ruma_api(query)]
|
||||
@ -63,6 +63,7 @@ ruma_api! {
|
||||
pub filter: Option<RoomEventFilter>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
response: {
|
||||
/// The token the pagination starts from.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@ -84,15 +85,22 @@ ruma_api! {
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
impl Request {
|
||||
impl<'a> Request<'a> {
|
||||
/// Creates a `Request` with the given parameters.
|
||||
///
|
||||
/// All other parameters will be defaulted.
|
||||
pub fn new(room_id: RoomId, from: String, dir: Direction) -> Self {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates an empty `Response`.
|
||||
pub fn new() -> Self {
|
||||
Self { start: None, end: None, chunk: Vec::new(), state: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
fn default_limit() -> UInt {
|
||||
uint!(10)
|
||||
}
|
||||
@ -135,9 +143,9 @@ mod tests {
|
||||
..Default::default()
|
||||
};
|
||||
let req = Request {
|
||||
room_id,
|
||||
from: "token".into(),
|
||||
to: Some("token2".into()),
|
||||
room_id: &room_id,
|
||||
from: "token",
|
||||
to: Some("token2"),
|
||||
dir: Direction::Backward,
|
||||
limit: uint!(0),
|
||||
filter: Some(filter),
|
||||
@ -161,9 +169,9 @@ mod tests {
|
||||
fn test_serialize_none_room_event_filter() {
|
||||
let room_id = room_id!("!roomid:example.org");
|
||||
let req = Request {
|
||||
room_id,
|
||||
from: "token".into(),
|
||||
to: Some("token2".into()),
|
||||
room_id: &room_id,
|
||||
from: "token",
|
||||
to: Some("token2"),
|
||||
dir: Direction::Backward,
|
||||
limit: uint!(0),
|
||||
filter: None,
|
||||
@ -178,9 +186,9 @@ mod tests {
|
||||
fn test_serialize_default_room_event_filter() {
|
||||
let room_id = room_id!("!roomid:example.org");
|
||||
let req = Request {
|
||||
room_id,
|
||||
from: "token".into(),
|
||||
to: Some("token2".into()),
|
||||
room_id: &room_id,
|
||||
from: "token",
|
||||
to: Some("token2"),
|
||||
dir: Direction::Backward,
|
||||
limit: uint!(0),
|
||||
filter: Some(RoomEventFilter::default()),
|
||||
|
@ -3,7 +3,7 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use js_int::{uint, UInt};
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_api::{ruma_api, Outgoing};
|
||||
use ruma_common::Raw;
|
||||
use ruma_events::{AnyEvent, AnyStateEvent};
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
@ -21,17 +21,19 @@ ruma_api! {
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
request: {
|
||||
/// The point to return events from.
|
||||
///
|
||||
/// If given, this should be a `next_batch` result from a previous call to this endpoint.
|
||||
#[ruma_api(query)]
|
||||
pub next_batch: Option<String>,
|
||||
pub next_batch: Option<&'a str>,
|
||||
|
||||
/// Describes which categories to search in and their criteria.
|
||||
pub search_categories: Categories,
|
||||
pub search_categories: Categories<'a>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
response: {
|
||||
/// A grouping of search results by category.
|
||||
pub search_categories: ResultCategories,
|
||||
@ -40,23 +42,45 @@ ruma_api! {
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
impl<'a> Request<'a> {
|
||||
/// Creates a new `Request` with the given categories.
|
||||
pub fn new(search_categories: Categories<'a>) -> Self {
|
||||
Self { next_batch: None, search_categories }
|
||||
}
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates a new `Response` with the given search results.
|
||||
pub fn new(search_categories: ResultCategories) -> Self {
|
||||
Self { search_categories }
|
||||
}
|
||||
}
|
||||
|
||||
/// Categories of events that can be searched for.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Categories {
|
||||
/// Criteria for searching a category of events.
|
||||
#[derive(Clone, Debug, Outgoing, Serialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct Categories<'a> {
|
||||
/// Criteria for searching room events.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub room_events: Option<Criteria>,
|
||||
pub room_events: Option<Criteria<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Categories<'a> {
|
||||
/// Creates an empty `Categories`.
|
||||
pub fn new() -> Self {
|
||||
Self { room_events: None }
|
||||
}
|
||||
}
|
||||
|
||||
/// Criteria for searching a category of events.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Criteria {
|
||||
#[derive(Clone, Debug, Outgoing, Serialize)]
|
||||
pub struct Criteria<'a> {
|
||||
/// The string to search events for.
|
||||
pub search_term: String,
|
||||
pub search_term: &'a str,
|
||||
|
||||
/// The keys to search for. Defaults to all keys.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub keys: Option<Vec<SearchKeys>>,
|
||||
pub keys: Option<&'a [SearchKeys]>,
|
||||
|
||||
/// A `Filter` to apply to the search.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@ -76,7 +100,7 @@ pub struct Criteria {
|
||||
|
||||
/// Requests that the server partitions the result set based on the provided list of keys.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub groupings: Option<Groupings>,
|
||||
pub groupings: Option<Groupings<'a>>,
|
||||
}
|
||||
|
||||
/// Configures whether any context for the events returned are included in the response.
|
||||
@ -154,11 +178,11 @@ pub enum GroupingKey {
|
||||
}
|
||||
|
||||
/// Requests that the server partitions the result set based on the provided list of keys.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Groupings {
|
||||
#[derive(Clone, Copy, Debug, Outgoing, Serialize)]
|
||||
pub struct Groupings<'a> {
|
||||
/// List of groups to request.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub group_by: Vec<Grouping>,
|
||||
#[serde(default, skip_serializing_if = "<[_]>::is_empty")]
|
||||
pub group_by: &'a [Grouping],
|
||||
}
|
||||
|
||||
/// The keys to search for.
|
||||
|
@ -16,12 +16,14 @@ ruma_api! {
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
request: {
|
||||
/// The user to look up.
|
||||
#[ruma_api(path)]
|
||||
pub user_id: UserId,
|
||||
pub user_id: &'a UserId,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
response: {
|
||||
/// The Matrix user ID of the user.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@ -35,6 +37,20 @@ ruma_api! {
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
impl<'a> Request<'a> {
|
||||
/// Creates a new `Request` with the given user id.
|
||||
pub fn new(user_id: &'a UserId) -> Self {
|
||||
Self { user_id }
|
||||
}
|
||||
}
|
||||
|
||||
impl Response {
|
||||
/// Creates an empty `Response`.
|
||||
pub fn new() -> Self {
|
||||
Self { user_id: None, devices: BTreeMap::new() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about a user's device.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct DeviceInfo {
|
||||
|
@ -64,7 +64,7 @@ ruma_api! {
|
||||
}
|
||||
|
||||
/// Identification information for the user.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Outgoing, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Outgoing, Serialize)]
|
||||
#[serde(from = "user_serde::IncomingUserInfo", into = "user_serde::UserInfo")]
|
||||
pub enum UserInfo<'a> {
|
||||
/// Either a fully qualified Matrix user ID, or just the localpart (as part of the 'identifier'
|
||||
@ -92,7 +92,7 @@ pub enum UserInfo<'a> {
|
||||
}
|
||||
|
||||
/// The authentication mechanism.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Outgoing, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Outgoing, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum LoginInfo<'a> {
|
||||
/// A password is supplied to authenticate.
|
||||
|
@ -3,7 +3,7 @@
|
||||
use std::{collections::BTreeMap, time::Duration};
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_api::{ruma_api, Outgoing};
|
||||
use ruma_common::{presence::PresenceState, Raw};
|
||||
use ruma_events::{
|
||||
presence::PresenceEvent, AnyBasicEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent,
|
||||
@ -28,7 +28,7 @@ ruma_api! {
|
||||
/// 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>,
|
||||
pub filter: Option<Filter<'a>>,
|
||||
|
||||
/// A point in time to continue a sync from.
|
||||
///
|
||||
@ -36,7 +36,7 @@ ruma_api! {
|
||||
/// request.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[ruma_api(query)]
|
||||
pub since: Option<String>,
|
||||
pub since: Option<&'a str>,
|
||||
|
||||
/// Controls whether to include the full state for all rooms the user is a member of.
|
||||
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
||||
@ -94,10 +94,10 @@ ruma_api! {
|
||||
}
|
||||
|
||||
/// A filter represented either as its full JSON definition or the ID of a saved filter.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, Outgoing, Serialize)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[serde(untagged)]
|
||||
pub enum Filter {
|
||||
pub enum Filter<'a> {
|
||||
// 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
|
||||
@ -113,7 +113,7 @@ pub enum Filter {
|
||||
FilterDefinition(FilterDefinition),
|
||||
|
||||
/// The ID of a filter saved on the server.
|
||||
FilterId(String),
|
||||
FilterId(&'a str),
|
||||
}
|
||||
|
||||
/// Updates to rooms.
|
||||
@ -408,13 +408,13 @@ mod tests {
|
||||
|
||||
use matches::assert_matches;
|
||||
|
||||
use super::{Filter, PresenceState, Request, Timeline};
|
||||
use super::{Filter, IncomingFilter, IncomingRequest, PresenceState, Request, Timeline};
|
||||
|
||||
#[test]
|
||||
fn serialize_all_params() {
|
||||
let req: http::Request<Vec<u8>> = Request {
|
||||
filter: Some(Filter::FilterId("66696p746572".into())),
|
||||
since: Some("s72594_4483_1934".into()),
|
||||
filter: Some(Filter::FilterId("66696p746572")),
|
||||
since: Some("s72594_4483_1934"),
|
||||
full_state: true,
|
||||
set_presence: PresenceState::Offline,
|
||||
timeout: Some(Duration::from_millis(30000)),
|
||||
@ -449,10 +449,10 @@ mod tests {
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let req: Request =
|
||||
let req: IncomingRequest =
|
||||
http::Request::builder().uri(uri).body(Vec::<u8>::new()).unwrap().try_into().unwrap();
|
||||
|
||||
assert_matches!(req.filter, Some(Filter::FilterId(id)) if id == "myfilter");
|
||||
assert_matches!(req.filter, Some(IncomingFilter::FilterId(id)) if id == "myfilter");
|
||||
assert_eq!(req.since, Some("myts".into()));
|
||||
assert_eq!(req.full_state, false);
|
||||
assert_eq!(req.set_presence, PresenceState::Offline);
|
||||
@ -468,7 +468,7 @@ mod tests {
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let req: Request =
|
||||
let req: IncomingRequest =
|
||||
http::Request::builder().uri(uri).body(Vec::<u8>::new()).unwrap().try_into().unwrap();
|
||||
|
||||
assert_matches!(req.filter, None);
|
||||
@ -491,10 +491,10 @@ mod tests {
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let req: Request =
|
||||
let req: IncomingRequest =
|
||||
http::Request::builder().uri(uri).body(Vec::<u8>::new()).unwrap().try_into().unwrap();
|
||||
|
||||
assert_matches!(req.filter, Some(Filter::FilterId(id)) if id == "EOKFFmdZYF");
|
||||
assert_matches!(req.filter, Some(IncomingFilter::FilterId(id)) if id == "EOKFFmdZYF");
|
||||
assert_eq!(req.since, None);
|
||||
assert_eq!(req.full_state, false);
|
||||
assert_eq!(req.set_presence, PresenceState::Online);
|
||||
|
@ -319,24 +319,25 @@ where
|
||||
/// If the since parameter is None, the first Item might take a significant time to arrive and
|
||||
/// be deserialized, because it contains all events that have occurred in the whole lifetime of
|
||||
/// the logged-in users account and are visible to them.
|
||||
pub fn sync(
|
||||
pub fn sync<'a>(
|
||||
&self,
|
||||
filter: Option<SyncFilter>,
|
||||
filter: Option<SyncFilter<'a>>,
|
||||
since: Option<String>,
|
||||
set_presence: ruma_common::presence::PresenceState,
|
||||
timeout: Option<Duration>,
|
||||
) -> impl Stream<Item = Result<SyncResponse, Error<ruma_client_api::Error>>>
|
||||
+ TryStream<Ok = SyncResponse, Error = Error<ruma_client_api::Error>> {
|
||||
+ TryStream<Ok = SyncResponse, Error = Error<ruma_client_api::Error>>
|
||||
+ 'a {
|
||||
let client = self.clone();
|
||||
stream::try_unfold(since, move |since| {
|
||||
let client = client.clone();
|
||||
let filter = filter.clone();
|
||||
let filter = filter.clone(); // FIXME: Remove once `SyncFilter` is `Copy`
|
||||
|
||||
async move {
|
||||
let response = client
|
||||
.request(SyncRequest {
|
||||
filter,
|
||||
since,
|
||||
since: since.as_deref(),
|
||||
full_state: false,
|
||||
set_presence,
|
||||
timeout,
|
||||
|
Loading…
x
Reference in New Issue
Block a user