From 10adf0c0c02c631e9839520d50173fd78b06b7bc Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sun, 18 Apr 2021 12:23:03 +0200 Subject: [PATCH] client-api: Use Raw in send_message_event, send_state_event --- .../src/r0/message/send_message_event.rs | 140 +++++------------ .../src/r0/state/send_state_event.rs | 142 ++++-------------- 2 files changed, 67 insertions(+), 215 deletions(-) diff --git a/ruma-client-api/src/r0/message/send_message_event.rs b/ruma-client-api/src/r0/message/send_message_event.rs index aba490af..e53261f6 100644 --- a/ruma-client-api/src/r0/message/send_message_event.rs +++ b/ruma-client-api/src/r0/message/send_message_event.rs @@ -1,9 +1,9 @@ //! [PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}](https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid) use ruma_api::ruma_api; -use ruma_events::AnyMessageEventContent; +use ruma_events::{AnyMessageEventContent, EventContent as _}; use ruma_identifiers::{EventId, RoomId}; -use ruma_serde::Outgoing; +use ruma_serde::Raw; ruma_api! { metadata: { @@ -15,6 +15,28 @@ ruma_api! { authentication: AccessToken, } + request: { + /// The room to send the event to. + #[ruma_api(path)] + pub room_id: &'a RoomId, + + /// The transaction ID for this event. + /// + /// Clients should generate an ID unique across requests with the + /// same access token; it will be used by the server to ensure + /// idempotency of requests. + #[ruma_api(path)] + pub txn_id: &'a str, + + /// The type of event to send. + #[ruma_api(path)] + pub event_type: &'a str, + + /// The event content to send. + #[ruma_api(body)] + pub body: Raw, + } + response: { /// A unique identifier for the event. pub event_id: EventId, @@ -23,31 +45,21 @@ ruma_api! { error: crate::Error } -/// Data for a request to the `send_message_event` API endpoint. -/// -/// Send a message event to a room. -#[derive(Clone, Debug, Outgoing)] -#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -#[incoming_derive(!Deserialize)] -pub struct Request<'a> { - /// The room to send the event to. - pub room_id: &'a RoomId, - - /// The transaction ID for this event. - /// - /// Clients should generate an ID unique across requests with the - /// same access token; it will be used by the server to ensure - /// idempotency of requests. - pub txn_id: &'a str, - - /// The event content to send. - pub content: &'a AnyMessageEventContent, -} - impl<'a> Request<'a> { /// Creates a new `Request` with the given room id, transaction id and event content. pub fn new(room_id: &'a RoomId, txn_id: &'a str, content: &'a AnyMessageEventContent) -> Self { - Self { room_id, txn_id, content } + Self { room_id, txn_id, event_type: content.event_type(), body: content.into() } + } + + /// Creates a new `Request` with the given room id, transaction id, event type and raw event + /// content. + pub fn new_raw( + room_id: &'a RoomId, + txn_id: &'a str, + event_type: &'a str, + body: Raw, + ) -> Self { + Self { room_id, txn_id, event_type, body } } } @@ -57,83 +69,3 @@ impl Response { Self { event_id } } } - -#[cfg(feature = "client")] -impl<'a> ruma_api::OutgoingRequest for Request<'a> { - type EndpointError = crate::Error; - type IncomingResponse = Response; - - const METADATA: ruma_api::Metadata = METADATA; - - fn try_into_http_request( - self, - base_url: &str, - access_token: Option<&str>, - ) -> Result>, ruma_api::error::IntoHttpError> { - use http::header::{HeaderValue, AUTHORIZATION, CONTENT_TYPE}; - use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; - use ruma_events::EventContent; - - let http_request = http::Request::builder() - .method(http::Method::PUT) - .uri(format!( - "{}/_matrix/client/r0/rooms/{}/send/{}/{}", - base_url.strip_suffix('/').unwrap_or(base_url), - utf8_percent_encode(self.room_id.as_str(), NON_ALPHANUMERIC), - utf8_percent_encode(self.content.event_type(), NON_ALPHANUMERIC), - utf8_percent_encode(&self.txn_id, NON_ALPHANUMERIC), - )) - .header(CONTENT_TYPE, "application/json") - .header( - AUTHORIZATION, - HeaderValue::from_str(&format!( - "Bearer {}", - access_token.ok_or(ruma_api::error::IntoHttpError::NeedsAuthentication)? - ))?, - ) - .body(serde_json::to_vec(&self.content)?)?; - - Ok(http_request) - } -} - -#[cfg(feature = "server")] -impl ruma_api::IncomingRequest for IncomingRequest { - type EndpointError = crate::Error; - type OutgoingResponse = Response; - - const METADATA: ruma_api::Metadata = METADATA; - - fn try_from_http_request>( - request: http::Request, - ) -> Result { - use std::convert::TryFrom; - - use ruma_events::EventContent as _; - use serde_json::value::RawValue as RawJsonValue; - - let (parts, body) = request.into_parts(); - let path_segments: Vec<&str> = parts.uri.path()[1..].split('/').collect(); - - let room_id = { - let decoded = - percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?; - - RoomId::try_from(&*decoded)? - }; - - let txn_id = percent_encoding::percent_decode(path_segments[7].as_bytes()) - .decode_utf8()? - .into_owned(); - - let content = { - let event_type = - percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?; - let body: Box = serde_json::from_slice(body.as_ref())?; - - AnyMessageEventContent::from_parts(&event_type, body)? - }; - - Ok(Self { room_id, txn_id, content }) - } -} diff --git a/ruma-client-api/src/r0/state/send_state_event.rs b/ruma-client-api/src/r0/state/send_state_event.rs index 63471094..550029d7 100644 --- a/ruma-client-api/src/r0/state/send_state_event.rs +++ b/ruma-client-api/src/r0/state/send_state_event.rs @@ -1,9 +1,9 @@ //! [PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}](https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey) use ruma_api::ruma_api; -use ruma_events::AnyStateEventContent; +use ruma_events::{AnyStateEventContent, EventContent as _}; use ruma_identifiers::{EventId, RoomId}; -use ruma_serde::Outgoing; +use ruma_serde::Raw; ruma_api! { metadata: { @@ -15,6 +15,24 @@ ruma_api! { authentication: AccessToken, } + request: { + /// The room to set the state in. + #[ruma_api(path)] + pub room_id: &'a RoomId, + + /// The type of event to send. + #[ruma_api(path)] + pub event_type: &'a str, + + /// The state_key for the state to send. + #[ruma_api(path)] + pub state_key: &'a str, + + /// The event content to send. + #[ruma_api(body)] + pub body: Raw, + } + response: { /// A unique identifier for the event. pub event_id: EventId, @@ -23,27 +41,20 @@ ruma_api! { error: crate::Error } -/// Data for a request to the `send_state_event` API endpoint. -/// -/// Send a state event to a room associated with a given state key. -#[derive(Clone, Debug, Outgoing)] -#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -#[incoming_derive(!Deserialize)] -pub struct Request<'a> { - /// The room to set the state in. - pub room_id: &'a RoomId, - - /// The state_key for the state to send. - pub state_key: &'a str, - - /// The event content to send. - pub content: &'a AnyStateEventContent, -} - impl<'a> Request<'a> { /// Creates a new `Request` with the given room id, state key and event content. pub fn new(room_id: &'a RoomId, state_key: &'a str, content: &'a AnyStateEventContent) -> Self { - Self { room_id, state_key, content } + Self { room_id, event_type: content.event_type(), body: content.into(), state_key } + } + + /// Creates a new `Request` with the given room id, event type, state key and raw event content. + pub fn new_raw( + room_id: &'a RoomId, + event_type: &'a str, + state_key: &'a str, + body: Raw, + ) -> Self { + Self { room_id, event_type, state_key, body } } } @@ -53,94 +64,3 @@ impl Response { Self { event_id } } } - -#[cfg(feature = "client")] -impl<'a> ruma_api::OutgoingRequest for Request<'a> { - type EndpointError = crate::Error; - type IncomingResponse = Response; - - const METADATA: ruma_api::Metadata = METADATA; - - fn try_into_http_request( - self, - base_url: &str, - access_token: Option<&str>, - ) -> Result>, ruma_api::error::IntoHttpError> { - use std::borrow::Cow; - - use http::header::{HeaderValue, AUTHORIZATION, CONTENT_TYPE}; - use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; - use ruma_events::EventContent; - - let mut url = format!( - "{}/_matrix/client/r0/rooms/{}/state/{}", - base_url.strip_suffix('/').unwrap_or(base_url), - utf8_percent_encode(self.room_id.as_str(), NON_ALPHANUMERIC), - utf8_percent_encode(self.content.event_type(), NON_ALPHANUMERIC), - ); - - if !self.state_key.is_empty() { - url.push('/'); - url.push_str(&Cow::from(utf8_percent_encode(&self.state_key, NON_ALPHANUMERIC))); - } - - let http_request = http::Request::builder() - .method(http::Method::PUT) - .uri(url) - .header(CONTENT_TYPE, "application/json") - .header( - AUTHORIZATION, - HeaderValue::from_str(&format!( - "Bearer {}", - access_token.ok_or(ruma_api::error::IntoHttpError::NeedsAuthentication)? - ))?, - ) - .body(serde_json::to_vec(&self.content)?)?; - - Ok(http_request) - } -} - -#[cfg(feature = "server")] -impl ruma_api::IncomingRequest for IncomingRequest { - type EndpointError = crate::Error; - type OutgoingResponse = Response; - - const METADATA: ruma_api::Metadata = METADATA; - - fn try_from_http_request>( - request: http::Request, - ) -> Result { - use std::{borrow::Cow, convert::TryFrom}; - - use ruma_events::EventContent as _; - use serde_json::value::RawValue as RawJsonValue; - - let (parts, body) = request.into_parts(); - let path_segments: Vec<&str> = parts.uri.path()[1..].split('/').collect(); - - let room_id = { - let decoded = - percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?; - - RoomId::try_from(&*decoded)? - }; - - let state_key = path_segments - .get(7) - .map(|segment| percent_encoding::percent_decode(segment.as_bytes()).decode_utf8()) - .transpose()? - .unwrap_or(Cow::Borrowed("")) - .into_owned(); - - let content = { - let event_type = - percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?; - let body: Box = serde_json::from_slice(body.as_ref())?; - - AnyStateEventContent::from_parts(&event_type, body)? - }; - - Ok(Self { room_id, state_key, content }) - } -}