matrix_sdk/widget/machine/incoming.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 ruma::{
16 api::client::{account::request_openid_token, delayed_events},
17 events::{AnyStateEvent, AnyTimelineEvent, AnyToDeviceEvent},
18 serde::Raw,
19};
20use serde::{Deserialize, Deserializer, de};
21use serde_json::value::RawValue as RawJsonValue;
22use uuid::Uuid;
23
24#[cfg(doc)]
25use super::MatrixDriverRequestData;
26use super::{
27 SendToDeviceEventResponse,
28 from_widget::{FromWidgetRequest, SendEventResponse},
29 to_widget::ToWidgetResponse,
30};
31use crate::widget::Capabilities;
32
33/// Incoming message for the widget client side module that it must process.
34pub(crate) enum IncomingMessage {
35 /// An incoming raw message from the widget.
36 WidgetMessage(String),
37
38 /// A response to a request to the `MatrixDriver`.
39 MatrixDriverResponse {
40 /// The ID of the request that this response corresponds to.
41 request_id: Uuid,
42
43 /// Result of the request: the response data, or a Matrix sdk error.
44 ///
45 /// Http errors will be forwarded to the widget in a specified format so
46 /// the widget can parse the error.
47 response: Result<MatrixDriverResponse, crate::Error>,
48 },
49
50 /// The `MatrixDriver` notified the `WidgetMachine` of a new Matrix event.
51 ///
52 /// This means that the machine previously subscribed to some events
53 /// ([`crate::widget::Action::SubscribeTimeline`] request).
54 MatrixEventReceived(Raw<AnyTimelineEvent>),
55
56 /// The `MatrixDriver` notified the `WidgetMachine` of a change in room
57 /// state.
58 ///
59 /// This means that the machine previously subscribed to some events
60 /// ([`crate::widget::Action::Subscribe`] request).
61 StateUpdateReceived(Vec<Raw<AnyStateEvent>>),
62
63 /// The `MatrixDriver` notified the `WidgetMachine` of a new to-device
64 /// event.
65 ToDeviceReceived(Raw<AnyToDeviceEvent>),
66}
67
68pub(crate) enum MatrixDriverResponse {
69 /// Client acquired capabilities from the user.
70 /// A response to a [`MatrixDriverRequestData::AcquireCapabilities`]
71 /// command.
72 CapabilitiesAcquired(Capabilities),
73 /// Client got OpenId token for a given request ID.
74 /// A response to a [`MatrixDriverRequestData::GetOpenId`] command.
75 OpenIdReceived(request_openid_token::v3::Response),
76 /// Client read some Matrix event(s).
77 /// A response to a [`MatrixDriverRequestData::ReadEvents`] command.
78 EventsRead(Vec<Raw<AnyTimelineEvent>>),
79 /// Client read some Matrix room state entries.
80 /// A response to a [`MatrixDriverRequestData::ReadState`] command.
81 StateRead(Vec<Raw<AnyStateEvent>>),
82 /// Client sent some Matrix event. The response contains the event ID.
83 /// A response to a [`MatrixDriverRequestData::SendEvent`] command.
84 EventSent(SendEventResponse),
85 /// A response to a `Action::SendToDevice` command.
86 ToDeviceSent(SendToDeviceEventResponse),
87 /// Client updated a delayed event.
88 /// A response to a [`MatrixDriverRequestData::UpdateDelayedEvent`] command.
89 DelayedEventUpdated(delayed_events::update_delayed_event::unstable::Response),
90}
91
92pub(super) struct IncomingWidgetMessage {
93 pub(super) widget_id: String,
94 pub(super) request_id: String,
95 pub(super) kind: IncomingWidgetMessageKind,
96}
97
98#[derive(Debug)]
99pub(super) enum IncomingWidgetMessageKind {
100 Request(Raw<FromWidgetRequest>),
101 Response(ToWidgetResponse),
102}
103
104impl<'de> Deserialize<'de> for IncomingWidgetMessage {
105 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
106 where
107 D: Deserializer<'de>,
108 {
109 let raw: Box<RawJsonValue> = Box::deserialize(deserializer)?;
110
111 #[derive(Deserialize)]
112 #[serde(rename_all = "camelCase")]
113 enum ApiTag {
114 FromWidget,
115 ToWidget,
116 }
117
118 #[derive(Deserialize)]
119 #[serde(rename_all = "camelCase")]
120 struct ExtractHeader {
121 api: ApiTag,
122 widget_id: String,
123 request_id: String,
124 }
125
126 let ExtractHeader { api, widget_id, request_id } =
127 serde_json::from_str(raw.get()).map_err(de::Error::custom)?;
128
129 let kind = match api {
130 ApiTag::FromWidget => IncomingWidgetMessageKind::Request(Raw::from_json(raw)),
131 ApiTag::ToWidget => serde_json::from_str(raw.get())
132 .map(IncomingWidgetMessageKind::Response)
133 .map_err(de::Error::custom)?,
134 };
135
136 Ok(Self { widget_id, request_id, kind })
137 }
138}