matrix_sdk/room/
messages.rs

1// Copyright 2023 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt;
16
17use matrix_sdk_common::{debug::DebugStructExt as _, deserialized_responses::TimelineEvent};
18use ruma::{
19    api::{
20        client::{filter::RoomEventFilter, message::get_message_events},
21        Direction,
22    },
23    assign,
24    events::AnyStateEvent,
25    serde::Raw,
26    uint, RoomId, UInt,
27};
28
29/// Options for [`messages`][super::Room::messages].
30///
31/// See that method and
32/// <https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv3roomsroomidmessages>
33/// for details.
34#[non_exhaustive]
35pub struct MessagesOptions {
36    /// The token to start returning events from.
37    ///
38    /// This token can be obtained from a `prev_batch` token returned for each
39    /// room from the sync API, or from a start or end token returned by a
40    /// previous `messages` call.
41    ///
42    /// If `from` isn't provided the homeserver shall return a list of messages
43    /// from the first or last (per the value of the dir parameter) visible
44    /// event in the room history for the requesting user.
45    pub from: Option<String>,
46
47    /// The token to stop returning events at.
48    ///
49    /// This token can be obtained from a `prev_batch` token returned for each
50    /// room by the sync API, or from a start or end token returned by a
51    /// previous `messages` call.
52    pub to: Option<String>,
53
54    /// The direction to return events in.
55    pub dir: Direction,
56
57    /// The maximum number of events to return.
58    ///
59    /// Default: 10.
60    pub limit: UInt,
61
62    /// A [`RoomEventFilter`] to filter returned events with.
63    pub filter: RoomEventFilter,
64}
65
66impl MessagesOptions {
67    /// Creates `MessagesOptions` with the given direction.
68    ///
69    /// All other parameters will be defaulted.
70    pub fn new(dir: Direction) -> Self {
71        Self { from: None, to: None, dir, limit: uint!(10), filter: RoomEventFilter::default() }
72    }
73
74    /// Creates `MessagesOptions` with `dir` set to `Backward`.
75    ///
76    /// If no `from` token is set afterwards, pagination will start at the
77    /// end of (the accessible part of) the room timeline.
78    pub fn backward() -> Self {
79        Self::new(Direction::Backward)
80    }
81
82    /// Creates `MessagesOptions` with `dir` set to `Forward`.
83    ///
84    /// If no `from` token is set afterwards, pagination will start at the
85    /// beginning of (the accessible part of) the room timeline.
86    pub fn forward() -> Self {
87        Self::new(Direction::Forward)
88    }
89
90    /// Creates a new `MessagesOptions` from `self` with the `from` field set to
91    /// the given value.
92    ///
93    /// Since the field is public, you can also assign to it directly. This
94    /// method merely acts as a shorthand for that, because it is very
95    /// common to set this field.
96    pub fn from<'a>(self, from: impl Into<Option<&'a str>>) -> Self {
97        Self { from: from.into().map(ToOwned::to_owned), ..self }
98    }
99
100    pub(super) fn into_request(self, room_id: &RoomId) -> get_message_events::v3::Request {
101        assign!(get_message_events::v3::Request::new(room_id.to_owned(), self.dir), {
102            from: self.from,
103            to: self.to,
104            limit: self.limit,
105            filter: self.filter,
106        })
107    }
108}
109
110#[cfg(not(tarpaulin_include))]
111impl fmt::Debug for MessagesOptions {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        let Self { from, to, dir, limit, filter } = self;
114
115        let mut s = f.debug_struct("MessagesOptions");
116        s.maybe_field("from", from).maybe_field("to", to).field("dir", dir).field("limit", limit);
117        if !filter.is_empty() {
118            s.field("filter", filter);
119        }
120        s.finish()
121    }
122}
123
124/// The result of a [`super::Room::messages`] call.
125///
126/// In short, this is a possibly decrypted version of the response of a
127/// `room/messages` api call.
128#[derive(Debug, Default)]
129pub struct Messages {
130    /// The token the pagination starts from.
131    pub start: String,
132
133    /// The token the pagination ends at.
134    pub end: Option<String>,
135
136    /// A list of room events.
137    pub chunk: Vec<TimelineEvent>,
138
139    /// A list of state events relevant to showing the `chunk`.
140    pub state: Vec<Raw<AnyStateEvent>>,
141}
142
143/// The result of a [`super::Room::event_with_context`] query.
144///
145/// This is a wrapper around
146/// [`ruma::api::client::context::get_context::v3::Response`], with events
147/// decrypted if needs be.
148#[derive(Debug, Default)]
149pub struct EventWithContextResponse {
150    /// The event targeted by the /context query.
151    pub event: Option<TimelineEvent>,
152
153    /// Events before the target event, if a non-zero context size was
154    /// requested.
155    ///
156    /// Like the corresponding Ruma response, these are in reverse chronological
157    /// order.
158    pub events_before: Vec<TimelineEvent>,
159
160    /// Events after the target event, if a non-zero context size was requested.
161    ///
162    /// Like the corresponding Ruma response, these are in chronological order.
163    pub events_after: Vec<TimelineEvent>,
164
165    /// Token to paginate backwards, aka "start" token.
166    pub prev_batch_token: Option<String>,
167
168    /// Token to paginate forwards, aka "end" token.
169    pub next_batch_token: Option<String>,
170
171    /// State events related to the request.
172    ///
173    /// If lazy-loading of members was requested, this may contain room
174    /// membership events.
175    pub state: Vec<Raw<AnyStateEvent>>,
176}