matrix_sdk/widget/machine/
driver_req.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
15//! A high-level API for requests that we send to the matrix driver.
16
17use std::marker::PhantomData;
18
19use ruma::{
20    api::client::{account::request_openid_token, delayed_events::update_delayed_event},
21    events::{AnyTimelineEvent, MessageLikeEventType, StateEventType, TimelineEventType},
22    serde::Raw,
23};
24use serde::Deserialize;
25use serde_json::value::RawValue as RawJsonValue;
26use tracing::error;
27
28use super::{
29    from_widget::SendEventResponse, incoming::MatrixDriverResponse, Action,
30    MatrixDriverRequestMeta, WidgetMachine,
31};
32use crate::widget::{Capabilities, StateKeySelector};
33
34#[derive(Clone, Debug)]
35pub(crate) enum MatrixDriverRequestData {
36    /// Acquire capabilities from the user given the set of desired
37    /// capabilities.
38    ///
39    /// Must eventually be answered with
40    /// [`MatrixDriverResponse::CapabilitiesAcquired`].
41    AcquireCapabilities(AcquireCapabilities),
42
43    /// Get OpenId token for a given request ID.
44    GetOpenId,
45
46    /// Read message event(s).
47    ReadMessageLikeEvent(ReadMessageLikeEventRequest),
48
49    /// Read state event(s).
50    ReadStateEvent(ReadStateEventRequest),
51
52    /// Send matrix event that corresponds to the given description.
53    SendMatrixEvent(SendEventRequest),
54
55    /// Data for sending a UpdateDelayedEvent client server api request.
56    UpdateDelayedEvent(UpdateDelayedEventRequest),
57}
58
59/// A handle to a pending `toWidget` request.
60pub(crate) struct MatrixDriverRequestHandle<'m, T> {
61    request_meta: Option<&'m mut MatrixDriverRequestMeta>,
62    _phantom: PhantomData<fn() -> T>,
63}
64
65impl<'m, T> MatrixDriverRequestHandle<'m, T>
66where
67    T: FromMatrixDriverResponse,
68{
69    pub(crate) fn new(request_meta: &'m mut MatrixDriverRequestMeta) -> Self {
70        Self { request_meta: Some(request_meta), _phantom: PhantomData }
71    }
72
73    pub(crate) fn null() -> Self {
74        Self { request_meta: None, _phantom: PhantomData }
75    }
76
77    /// Setup a callback function that will be called once the matrix driver has
78    /// processed the request.
79    pub(crate) fn then(
80        self,
81        response_handler: impl FnOnce(Result<T, crate::Error>, &mut WidgetMachine) -> Vec<Action>
82            + Send
83            + 'static,
84    ) {
85        if let Some(request_meta) = self.request_meta {
86            request_meta.response_fn = Some(Box::new(move |response, machine| {
87                if let Some(response_data) = response.map(T::from_response).transpose() {
88                    response_handler(response_data, machine)
89                } else {
90                    Vec::new()
91                }
92            }));
93        }
94    }
95}
96
97/// Represents a request that the widget API state machine can send.
98pub(crate) trait MatrixDriverRequest: Into<MatrixDriverRequestData> {
99    type Response: FromMatrixDriverResponse;
100}
101
102pub(crate) trait FromMatrixDriverResponse: Sized {
103    fn from_response(_: MatrixDriverResponse) -> Option<Self>;
104}
105
106/// Ask the client (capability provider) to acquire given capabilities
107/// from the user. The client must eventually respond with granted capabilities.
108#[derive(Clone, Debug)]
109pub(crate) struct AcquireCapabilities {
110    pub(crate) desired_capabilities: Capabilities,
111}
112
113impl From<AcquireCapabilities> for MatrixDriverRequestData {
114    fn from(value: AcquireCapabilities) -> Self {
115        MatrixDriverRequestData::AcquireCapabilities(value)
116    }
117}
118
119impl MatrixDriverRequest for AcquireCapabilities {
120    type Response = Capabilities;
121}
122
123impl FromMatrixDriverResponse for Capabilities {
124    fn from_response(ev: MatrixDriverResponse) -> Option<Self> {
125        match ev {
126            MatrixDriverResponse::CapabilitiesAcquired(response) => Some(response),
127            _ => {
128                error!("bug in MatrixDriver, received wrong event response");
129                None
130            }
131        }
132    }
133}
134
135/// Request open ID from the Matrix client.
136#[derive(Debug)]
137pub(crate) struct RequestOpenId;
138
139impl From<RequestOpenId> for MatrixDriverRequestData {
140    fn from(_: RequestOpenId) -> Self {
141        MatrixDriverRequestData::GetOpenId
142    }
143}
144
145impl MatrixDriverRequest for RequestOpenId {
146    type Response = request_openid_token::v3::Response;
147}
148
149impl FromMatrixDriverResponse for request_openid_token::v3::Response {
150    fn from_response(ev: MatrixDriverResponse) -> Option<Self> {
151        match ev {
152            MatrixDriverResponse::OpenIdReceived(response) => Some(response),
153            _ => {
154                error!("bug in MatrixDriver, received wrong event response");
155                None
156            }
157        }
158    }
159}
160
161/// Ask the client to read matrix event(s) that corresponds to the given
162/// description and return a list of events as a response.
163#[derive(Clone, Debug)]
164pub(crate) struct ReadMessageLikeEventRequest {
165    /// The event type to read.
166    pub(crate) event_type: MessageLikeEventType,
167
168    /// The maximum number of events to return.
169    pub(crate) limit: u32,
170}
171
172impl From<ReadMessageLikeEventRequest> for MatrixDriverRequestData {
173    fn from(value: ReadMessageLikeEventRequest) -> Self {
174        MatrixDriverRequestData::ReadMessageLikeEvent(value)
175    }
176}
177
178impl MatrixDriverRequest for ReadMessageLikeEventRequest {
179    type Response = Vec<Raw<AnyTimelineEvent>>;
180}
181
182impl FromMatrixDriverResponse for Vec<Raw<AnyTimelineEvent>> {
183    fn from_response(ev: MatrixDriverResponse) -> Option<Self> {
184        match ev {
185            MatrixDriverResponse::MatrixEventRead(response) => Some(response),
186            _ => {
187                error!("bug in MatrixDriver, received wrong event response");
188                None
189            }
190        }
191    }
192}
193
194/// Ask the client to read matrix event(s) that corresponds to the given
195/// description and return a list of events as a response.
196#[derive(Clone, Debug)]
197pub(crate) struct ReadStateEventRequest {
198    /// The event type to read.
199    pub(crate) event_type: StateEventType,
200
201    /// The `state_key` to read, or `Any` to receive any/all events of the given
202    /// type, regardless of their `state_key`.
203    pub(crate) state_key: StateKeySelector,
204}
205
206impl From<ReadStateEventRequest> for MatrixDriverRequestData {
207    fn from(value: ReadStateEventRequest) -> Self {
208        MatrixDriverRequestData::ReadStateEvent(value)
209    }
210}
211
212impl MatrixDriverRequest for ReadStateEventRequest {
213    type Response = Vec<Raw<AnyTimelineEvent>>;
214}
215
216/// Ask the client to send matrix event that corresponds to the given
217/// description and returns an event ID (or a delay ID,
218/// see [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140)) as a response.
219#[derive(Clone, Debug, Deserialize)]
220pub(crate) struct SendEventRequest {
221    /// The type of the event.
222    #[serde(rename = "type")]
223    pub(crate) event_type: TimelineEventType,
224    /// State key of an event (if it's a state event).
225    pub(crate) state_key: Option<String>,
226    /// Raw content of an event.
227    pub(crate) content: Box<RawJsonValue>,
228    /// The optional delay (in ms) to send the event at.
229    /// If provided, the response will contain a delay_id instead of a event_id.
230    /// Defined by [MSC4157](https://github.com/matrix-org/matrix-spec-proposals/pull/4157)
231    pub(crate) delay: Option<u64>,
232}
233
234impl From<SendEventRequest> for MatrixDriverRequestData {
235    fn from(value: SendEventRequest) -> Self {
236        MatrixDriverRequestData::SendMatrixEvent(value)
237    }
238}
239
240impl MatrixDriverRequest for SendEventRequest {
241    type Response = SendEventResponse;
242}
243
244impl FromMatrixDriverResponse for SendEventResponse {
245    fn from_response(ev: MatrixDriverResponse) -> Option<Self> {
246        match ev {
247            MatrixDriverResponse::MatrixEventSent(response) => Some(response),
248            _ => {
249                error!("bug in MatrixDriver, received wrong event response");
250                None
251            }
252        }
253    }
254}
255
256/// Ask the client to send a UpdateDelayedEventRequest with the given `delay_id`
257/// and `action`. Defined by [MSC4157](https://github.com/matrix-org/matrix-spec-proposals/pull/4157)
258#[derive(Deserialize, Debug, Clone)]
259pub(crate) struct UpdateDelayedEventRequest {
260    pub(crate) action: update_delayed_event::unstable::UpdateAction,
261    pub(crate) delay_id: String,
262}
263
264impl From<UpdateDelayedEventRequest> for MatrixDriverRequestData {
265    fn from(value: UpdateDelayedEventRequest) -> Self {
266        MatrixDriverRequestData::UpdateDelayedEvent(value)
267    }
268}
269
270impl MatrixDriverRequest for UpdateDelayedEventRequest {
271    type Response = update_delayed_event::unstable::Response;
272}
273
274impl FromMatrixDriverResponse for update_delayed_event::unstable::Response {
275    fn from_response(ev: MatrixDriverResponse) -> Option<Self> {
276        match ev {
277            MatrixDriverResponse::MatrixDelayedEventUpdate(response) => Some(response),
278            _ => {
279                error!("bug in MatrixDriver, received wrong event response");
280                None
281            }
282        }
283    }
284}