matrix_sdk/widget/machine/incoming.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ruma::{
api::client::{account::request_openid_token, delayed_events},
events::AnyTimelineEvent,
serde::Raw,
};
use serde::{de, Deserialize, Deserializer};
use serde_json::value::RawValue as RawJsonValue;
use uuid::Uuid;
use super::{
from_widget::{FromWidgetRequest, SendEventResponse},
to_widget::ToWidgetResponse,
};
use crate::widget::Capabilities;
/// Incoming event that the client API must process.
pub(crate) enum IncomingMessage {
/// An incoming raw message from the widget.
WidgetMessage(String),
/// A response to a request to the `MatrixDriver`.
MatrixDriverResponse {
/// The ID of the request that this response corresponds to.
request_id: Uuid,
/// Result of the request: the response data, or a matrix sdk error.
///
/// Http errors will be forwarded to the widget in a specified format so
/// the widget can parse the error.
response: Result<MatrixDriverResponse, crate::Error>,
},
/// The `MatrixDriver` notified the `WidgetMachine` of a new matrix event.
///
/// This means that the machine previously subscribed to some events
/// ([`crate::widget::Action::Subscribe`] request).
MatrixEventReceived(Raw<AnyTimelineEvent>),
}
pub(crate) enum MatrixDriverResponse {
/// Client acquired capabilities from the user.
///
/// A response to an `Action::AcquireCapabilities` command.
CapabilitiesAcquired(Capabilities),
/// Client got OpenId token for a given request ID.
/// A response to an `Action::GetOpenId` command.
OpenIdReceived(request_openid_token::v3::Response),
/// Client read some matrix event(s).
/// A response to an `Action::ReadMatrixEvent` commands.
MatrixEventRead(Vec<Raw<AnyTimelineEvent>>),
/// Client sent some matrix event. The response contains the event ID.
/// A response to an `Action::SendMatrixEvent` command.
MatrixEventSent(SendEventResponse),
MatrixDelayedEventUpdate(delayed_events::update_delayed_event::unstable::Response),
}
pub(super) struct IncomingWidgetMessage {
pub(super) widget_id: String,
pub(super) request_id: String,
pub(super) kind: IncomingWidgetMessageKind,
}
#[derive(Debug)]
pub(super) enum IncomingWidgetMessageKind {
Request(Raw<FromWidgetRequest>),
Response(ToWidgetResponse),
}
impl<'de> Deserialize<'de> for IncomingWidgetMessage {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let raw: Box<RawJsonValue> = Box::deserialize(deserializer)?;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
enum ApiTag {
FromWidget,
ToWidget,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct ExtractHeader {
api: ApiTag,
widget_id: String,
request_id: String,
}
let ExtractHeader { api, widget_id, request_id } =
serde_json::from_str(raw.get()).map_err(de::Error::custom)?;
let kind = match api {
ApiTag::FromWidget => IncomingWidgetMessageKind::Request(Raw::from_json(raw)),
ApiTag::ToWidget => serde_json::from_str(raw.get())
.map(IncomingWidgetMessageKind::Response)
.map_err(de::Error::custom)?,
};
Ok(Self { widget_id, request_id, kind })
}
}