widget: Remove unnecessary type wrapping

… and move some types around.
This commit is contained in:
Jonas Platte
2023-10-19 17:04:46 +02:00
committed by Jonas Platte
parent 489d699cc5
commit a2d05ed002
5 changed files with 110 additions and 150 deletions

View File

@@ -1,111 +0,0 @@
// 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::events::{MessageLikeEventType, StateEventType, TimelineEventType};
use serde::Deserialize;
use serde_json::Value as JsonValue;
use uuid::Uuid;
use super::driver_req::AcquireCapabilities;
#[cfg(doc)]
use super::incoming::MatrixDriverResponse;
use crate::widget::StateKeySelector;
/// Action (a command) that client (driver) must perform.
#[derive(Debug)]
pub(crate) enum Action {
/// Send a raw message to the widget.
SendToWidget(String),
/// Command that is sent from the client widget API state machine to the
/// client (driver) that must be performed. Once the command is executed,
/// the client will typically generate an `Event` with the result of it.
MatrixDriverRequest {
/// Certain commands are typically answered with certain event once the
/// command is performed. The api state machine will "tag" each command
/// with some "cookie" (in this case just an ID), so that once the
/// result of the execution of this command is received, it could be
/// matched.
request_id: Uuid,
/// Data associated with this command.
data: MatrixDriverRequestData,
},
/// Subscribe to the events in the *current* room, i.e. a room which this
/// widget is instantiated with. The client is aware of the room.
#[allow(dead_code)]
Subscribe,
/// Unsuscribe from the events in the *current* room. Symmetrical to
/// `Subscribe`.
#[allow(dead_code)]
Unsubscribe,
}
/// Command to read matrix message event(s).
#[derive(Debug)]
pub(crate) struct ReadMessageLikeEventCommand {
/// The event type to read.
pub(crate) event_type: MessageLikeEventType,
/// The maximum number of events to return.
pub(crate) limit: u32,
}
/// Command to read matrix state event(s).
#[derive(Debug)]
pub(crate) struct ReadStateEventCommand {
/// The event type to read.
pub(crate) event_type: StateEventType,
/// The `state_key` to read, or `Any` to receive any/all events of the given
/// type, regardless of their `state_key`.
pub(crate) state_key: StateKeySelector,
}
/// Command to send matrix event.
#[derive(Clone, Debug, Deserialize)]
pub(crate) struct SendEventCommand {
#[serde(rename = "type")]
/// type of an event.
pub(crate) event_type: TimelineEventType,
/// State key of an event (if it's a state event).
pub(crate) state_key: Option<String>,
/// Raw content of an event.
pub(crate) content: JsonValue,
}
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) enum MatrixDriverRequestData {
/// Acquire capabilities from the user given the set of desired
/// capabilities.
///
/// Must eventually be answered with
/// [`MatrixDriverResponse::CapabilitiesAcquired`].
AcquireCapabilities(AcquireCapabilities),
/// Get OpenId token for a given request ID.
GetOpenId,
/// Read message event(s).
ReadMessageLikeEvent(ReadMessageLikeEventCommand),
/// Read state event(s).
ReadStateEvent(ReadStateEventCommand),
/// Send matrix event that corresponds to the given description.
SendMatrixEvent(SendEventCommand),
}

View File

@@ -19,16 +19,40 @@
use std::marker::PhantomData;
use ruma::{
api::client::account::request_openid_token, events::AnyTimelineEvent, serde::Raw, OwnedEventId,
api::client::account::request_openid_token,
events::{AnyTimelineEvent, MessageLikeEventType, StateEventType, TimelineEventType},
serde::Raw,
OwnedEventId,
};
use serde::Deserialize;
use serde_json::Value as JsonValue;
use tracing::error;
use super::{
actions::{MatrixDriverRequestData, ReadMessageLikeEventCommand, ReadStateEventCommand},
incoming::MatrixDriverResponse,
MatrixDriverRequestMeta, SendEventCommand, WidgetMachine,
};
use crate::widget::Capabilities;
use super::{incoming::MatrixDriverResponse, MatrixDriverRequestMeta, WidgetMachine};
use crate::widget::{Capabilities, StateKeySelector};
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) enum MatrixDriverRequestData {
/// Acquire capabilities from the user given the set of desired
/// capabilities.
///
/// Must eventually be answered with
/// [`MatrixDriverResponse::CapabilitiesAcquired`].
AcquireCapabilities(AcquireCapabilities),
/// Get OpenId token for a given request ID.
GetOpenId,
/// Read message event(s).
ReadMessageLikeEvent(ReadMessageLikeEventRequest),
/// Read state event(s).
ReadStateEvent(ReadStateEventRequest),
/// Send matrix event that corresponds to the given description.
SendMatrixEvent(SendEventRequest),
}
/// A handle to a pending `toWidget` request.
pub(crate) struct MatrixDriverRequestHandle<'m, T> {
@@ -129,15 +153,21 @@ impl FromMatrixDriverResponse for request_openid_token::v3::Response {
/// Ask the client to read matrix event(s) that corresponds to the given
/// description and return a list of events as a response.
#[derive(Debug)]
pub(crate) struct ReadMatrixMessageLikeEvent(pub(crate) ReadMessageLikeEventCommand);
pub(crate) struct ReadMessageLikeEventRequest {
/// The event type to read.
pub(crate) event_type: MessageLikeEventType,
impl From<ReadMatrixMessageLikeEvent> for MatrixDriverRequestData {
fn from(value: ReadMatrixMessageLikeEvent) -> Self {
MatrixDriverRequestData::ReadMessageLikeEvent(value.0)
/// The maximum number of events to return.
pub(crate) limit: u32,
}
impl From<ReadMessageLikeEventRequest> for MatrixDriverRequestData {
fn from(value: ReadMessageLikeEventRequest) -> Self {
MatrixDriverRequestData::ReadMessageLikeEvent(value)
}
}
impl MatrixDriverRequest for ReadMatrixMessageLikeEvent {
impl MatrixDriverRequest for ReadMessageLikeEventRequest {
type Response = Vec<Raw<AnyTimelineEvent>>;
}
@@ -156,30 +186,45 @@ impl FromMatrixDriverResponse for Vec<Raw<AnyTimelineEvent>> {
/// Ask the client to read matrix event(s) that corresponds to the given
/// description and return a list of events as a response.
#[derive(Debug)]
pub(crate) struct ReadMatrixStateEvent(pub(crate) ReadStateEventCommand);
pub(crate) struct ReadStateEventRequest {
/// The event type to read.
pub(crate) event_type: StateEventType,
impl From<ReadMatrixStateEvent> for MatrixDriverRequestData {
fn from(value: ReadMatrixStateEvent) -> Self {
MatrixDriverRequestData::ReadStateEvent(value.0)
/// The `state_key` to read, or `Any` to receive any/all events of the given
/// type, regardless of their `state_key`.
pub(crate) state_key: StateKeySelector,
}
impl From<ReadStateEventRequest> for MatrixDriverRequestData {
fn from(value: ReadStateEventRequest) -> Self {
MatrixDriverRequestData::ReadStateEvent(value)
}
}
impl MatrixDriverRequest for ReadMatrixStateEvent {
impl MatrixDriverRequest for ReadStateEventRequest {
type Response = Vec<Raw<AnyTimelineEvent>>;
}
/// Ask the client to send matrix event that corresponds to the given
/// description and return an event ID as a response.
#[derive(Debug)]
pub(crate) struct SendMatrixEvent(pub(crate) SendEventCommand);
#[derive(Debug, Deserialize)]
pub(crate) struct SendEventRequest {
/// The type of the event.
#[serde(rename = "type")]
pub(crate) event_type: TimelineEventType,
/// State key of an event (if it's a state event).
pub(crate) state_key: Option<String>,
/// Raw content of an event.
pub(crate) content: JsonValue,
}
impl From<SendMatrixEvent> for MatrixDriverRequestData {
fn from(value: SendMatrixEvent) -> Self {
MatrixDriverRequestData::SendMatrixEvent(value.0)
impl From<SendEventRequest> for MatrixDriverRequestData {
fn from(value: SendEventRequest) -> Self {
MatrixDriverRequestData::SendMatrixEvent(value)
}
}
impl MatrixDriverRequest for SendMatrixEvent {
impl MatrixDriverRequest for SendEventRequest {
type Response = OwnedEventId;
}

View File

@@ -21,7 +21,7 @@ use ruma::{
};
use serde::{Deserialize, Serialize};
use super::SendEventCommand;
use super::SendEventRequest;
use crate::widget::StateKeySelector;
#[derive(Deserialize)]
@@ -31,7 +31,7 @@ pub(super) enum FromWidgetRequest {
ContentLoaded {},
#[serde(rename = "org.matrix.msc2876.read_events")]
ReadEvent(ReadEventRequest),
SendEvent(SendEventCommand),
SendEvent(SendEventRequest),
}
#[derive(Serialize)]

View File

@@ -30,11 +30,7 @@ use tracing::{debug, error, info_span, instrument, trace, warn};
use uuid::Uuid;
use self::{
actions::ReadStateEventCommand,
driver_req::{
AcquireCapabilities, MatrixDriverRequest, MatrixDriverRequestHandle, ReadMatrixStateEvent,
SendMatrixEvent,
},
driver_req::{AcquireCapabilities, MatrixDriverRequest, MatrixDriverRequestHandle},
from_widget::{
FromWidgetErrorResponse, FromWidgetRequest, ReadEventRequest, ReadEventResponse,
SendEventResponse, SupportedApiVersionsResponse,
@@ -52,7 +48,6 @@ use super::{
Capabilities, StateKeySelector,
};
mod actions;
mod driver_req;
mod from_widget;
mod incoming;
@@ -62,10 +57,42 @@ mod tests;
mod to_widget;
pub(crate) use self::{
actions::{Action, MatrixDriverRequestData, SendEventCommand},
driver_req::{MatrixDriverRequestData, ReadStateEventRequest, SendEventRequest},
incoming::{IncomingMessage, MatrixDriverResponse},
};
/// Action (a command) that client (driver) must perform.
#[derive(Debug)]
pub(crate) enum Action {
/// Send a raw message to the widget.
SendToWidget(String),
/// Command that is sent from the client widget API state machine to the
/// client (driver) that must be performed. Once the command is executed,
/// the client will typically generate an `Event` with the result of it.
MatrixDriverRequest {
/// Certain commands are typically answered with certain event once the
/// command is performed. The api state machine will "tag" each command
/// with some "cookie" (in this case just an ID), so that once the
/// result of the execution of this command is received, it could be
/// matched.
request_id: Uuid,
/// Data associated with this command.
data: MatrixDriverRequestData,
},
/// Subscribe to the events in the *current* room, i.e. a room which this
/// widget is instantiated with. The client is aware of the room.
#[allow(dead_code)]
Subscribe,
/// Unsuscribe from the events in the *current* room. Symmetrical to
/// `Subscribe`.
#[allow(dead_code)]
Unsubscribe,
}
/// No I/O state machine.
///
/// Handles interactions with the widget as well as the `MatrixDriver`.
@@ -219,8 +246,7 @@ impl WidgetMachine {
};
if allowed {
let request =
ReadMatrixStateEvent(ReadStateEventCommand { event_type, state_key });
let request = ReadStateEventRequest { event_type, state_key };
self.send_matrix_driver_request(request).then(|events, machine| {
machine
.send_from_widget_response(raw_request, ReadEventResponse { events });
@@ -234,7 +260,7 @@ impl WidgetMachine {
fn process_send_event_request(
&mut self,
request: SendEventCommand,
request: SendEventRequest,
raw_request: Raw<FromWidgetRequest>,
) {
let CapabilitiesState::Negotiated(capabilities) = &self.capabilities else {
@@ -254,7 +280,7 @@ impl WidgetMachine {
};
if capabilities.send.iter().any(|filter| filter.matches(&filter_in)) {
self.send_matrix_driver_request(SendMatrixEvent(request)).then(|event_id, machine| {
self.send_matrix_driver_request(request).then(|event_id, machine| {
let response = SendEventResponse { event_id, room_id: &machine.room_id };
machine.send_from_widget_response(raw_request, response);
});

View File

@@ -23,7 +23,7 @@ use tokio_util::sync::{CancellationToken, DropGuard};
use self::{
machine::{
Action, IncomingMessage, MatrixDriverRequestData, MatrixDriverResponse, SendEventCommand,
Action, IncomingMessage, MatrixDriverRequestData, MatrixDriverResponse, SendEventRequest,
WidgetMachine,
},
matrix::MatrixDriver,
@@ -183,8 +183,8 @@ impl WidgetDriver {
.map(MatrixDriverResponse::MatrixEventRead)
.map_err(|e| e.to_string()),
MatrixDriverRequestData::SendMatrixEvent(cmd) => {
let SendEventCommand { event_type, state_key, content } = cmd.clone();
MatrixDriverRequestData::SendMatrixEvent(req) => {
let SendEventRequest { event_type, state_key, content } = req;
matrix_driver
.send(event_type, state_key, content)