matrix_sdk/paginators/
mod.rs

1// Copyright 2025 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
15//! Stateful paginators to help with paginated APIs.
16
17mod room;
18pub mod thread;
19
20use matrix_sdk_base::deserialized_responses::TimelineEvent;
21pub use room::*;
22use ruma::OwnedEventId;
23
24/// Pagination token data, indicating in which state is the current pagination.
25#[derive(Clone, Debug, PartialEq)]
26pub enum PaginationToken {
27    /// We never had a pagination token, so we'll start back-paginating from the
28    /// end, or forward-paginating from the start.
29    None,
30    /// We paginated once before, and we received a prev/next batch token that
31    /// we may reuse for the next query.
32    HasMore(String),
33    /// We've hit one end of the timeline (either the start or the actual end),
34    /// so there's no need to continue paginating.
35    HitEnd,
36}
37
38impl From<Option<String>> for PaginationToken {
39    fn from(token: Option<String>) -> Self {
40        match token {
41            Some(val) => Self::HasMore(val),
42            None => Self::None,
43        }
44    }
45}
46
47/// The result of a single event pagination.
48#[derive(Debug)]
49pub struct PaginationResult {
50    /// Events returned during this pagination.
51    ///
52    /// If this is the result of a backward pagination, then the events are in
53    /// reverse topological order.
54    ///
55    /// If this is the result of a forward pagination, then the events are in
56    /// topological order.
57    pub events: Vec<TimelineEvent>,
58
59    /// Did we hit *an* end of the timeline?
60    ///
61    /// If this is the result of a backward pagination, this means we hit the
62    /// *start* of the timeline.
63    ///
64    /// If this is the result of a forward pagination, this means we hit the
65    /// *end* of the timeline.
66    pub hit_end_of_timeline: bool,
67}
68
69/// An error that happened when using a [`Paginator`].
70#[derive(Debug, thiserror::Error)]
71pub enum PaginatorError {
72    /// The target event could not be found.
73    #[error("target event with id {0} could not be found")]
74    EventNotFound(OwnedEventId),
75
76    /// We're trying to manipulate the paginator in the wrong state.
77    #[error("expected paginator state {expected:?}, observed {actual:?}")]
78    InvalidPreviousState {
79        /// The state we were expecting to see.
80        expected: PaginatorState,
81        /// The actual state when doing the check.
82        actual: PaginatorState,
83    },
84
85    /// There was another SDK error while paginating.
86    #[error("an error happened while paginating: {0}")]
87    SdkError(#[from] Box<crate::Error>),
88}