diff --git a/ruma-federation-api/src/event.rs b/ruma-federation-api/src/event.rs index 9dad2955..9ba58435 100644 --- a/ruma-federation-api/src/event.rs +++ b/ruma-federation-api/src/event.rs @@ -1,3 +1,6 @@ //! Endpoints to get general information about events +pub mod get_event; pub mod get_missing_events; +pub mod get_room_state; +pub mod get_room_state_ids; diff --git a/ruma-federation-api/src/event/get_event.rs b/ruma-federation-api/src/event/get_event.rs new file mode 100644 index 00000000..767985e3 --- /dev/null +++ b/ruma-federation-api/src/event/get_event.rs @@ -0,0 +1,3 @@ +//! Retrieves a single event. + +pub mod v1; diff --git a/ruma-federation-api/src/event/get_event/v1.rs b/ruma-federation-api/src/event/get_event/v1.rs new file mode 100644 index 00000000..b6c1f1ec --- /dev/null +++ b/ruma-federation-api/src/event/get_event/v1.rs @@ -0,0 +1,52 @@ +//! [GET /_matrix/federation/v1/event/{eventId}](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-federation-v1-event-eventid) + +use ruma_api::ruma_api; +use ruma_events::pdu::Pdu; +use ruma_identifiers::{EventId, ServerNameBox}; +use std::time::SystemTime; + +ruma_api! { + metadata: { + description: "Retrieves a single event.", + method: GET, + name: "get_event", + path: "/_matrix/federation/v1/event/:event_id", + rate_limited: false, + requires_authentication: true, + } + + #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] + request: { + /// The event ID to get. + #[ruma_api(path)] + pub event_id: &'a EventId, + } + + #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] + response: { + /// The `server_name` of the homeserver sending this transaction. + pub origin: ServerNameBox, + + /// Time on originating homeserver when this transaction started. + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] + pub origin_server_ts: SystemTime, + + /// The event. + #[serde(rename = "pdus", with = "ruma_serde::single_element_seq")] + pub pdu: Pdu, + } +} + +impl<'a> Request<'a> { + /// Creates a new `Request` with the given event id. + pub fn new(event_id: &'a EventId) -> Self { + Self { event_id } + } +} + +impl Response { + /// Creates a new `Response` with the given server name, timestamp, and event. + pub fn new(origin: ServerNameBox, origin_server_ts: SystemTime, pdu: Pdu) -> Self { + Self { origin, origin_server_ts, pdu } + } +} diff --git a/ruma-federation-api/src/event/get_room_state.rs b/ruma-federation-api/src/event/get_room_state.rs new file mode 100644 index 00000000..f59e8204 --- /dev/null +++ b/ruma-federation-api/src/event/get_room_state.rs @@ -0,0 +1,3 @@ +//! Retrieves a snapshot of a room's state at a given event. + +pub mod v1; diff --git a/ruma-federation-api/src/event/get_room_state/v1.rs b/ruma-federation-api/src/event/get_room_state/v1.rs new file mode 100644 index 00000000..e96e2cfe --- /dev/null +++ b/ruma-federation-api/src/event/get_room_state/v1.rs @@ -0,0 +1,51 @@ +//! [GET /_matrix/federation/v1/state/{roomId}](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-federation-v1-state-roomid) + +use ruma_api::ruma_api; +use ruma_events::pdu::Pdu; +use ruma_identifiers::{EventId, RoomId}; + +ruma_api! { + metadata: { + description: "Retrieves a snapshot of a room's state at a given event.", + method: GET, + name: "get_room_state", + path: "/_matrix/federation/v1/state/:room_id", + rate_limited: false, + requires_authentication: true, + } + + #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] + request: { + /// The room ID to get state for. + #[ruma_api(path)] + pub room_id: &'a RoomId, + + /// An event ID in the room to retrieve the state at. + #[ruma_api(query)] + pub event_id: &'a EventId, + } + + #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] + response: { + /// The full set of authorization events that make up the state of the + /// room, and their authorization events, recursively. + pub auth_chain: Vec, + + /// The fully resolved state of the room at the given event. + pub pdus: Vec, + } +} + +impl<'a> Request<'a> { + /// Creates a new `Request` with the given event ID and room ID. + pub fn new(event_id: &'a EventId, room_id: &'a RoomId) -> Self { + Self { event_id, room_id } + } +} + +impl Response { + /// Creates a new `Response` with the given auth chain and room state. + pub fn new(auth_chain: Vec, pdus: Vec) -> Self { + Self { auth_chain, pdus } + } +} diff --git a/ruma-federation-api/src/event/get_room_state_ids.rs b/ruma-federation-api/src/event/get_room_state_ids.rs new file mode 100644 index 00000000..6d0e7e60 --- /dev/null +++ b/ruma-federation-api/src/event/get_room_state_ids.rs @@ -0,0 +1,3 @@ +//! Retrieves a snapshot of a room's state at a given event, in the form of event IDs. + +pub mod v1; diff --git a/ruma-federation-api/src/event/get_room_state_ids/v1.rs b/ruma-federation-api/src/event/get_room_state_ids/v1.rs new file mode 100644 index 00000000..d899975f --- /dev/null +++ b/ruma-federation-api/src/event/get_room_state_ids/v1.rs @@ -0,0 +1,50 @@ +//! [GET /_matrix/federation/v1/state_ids/{roomId}](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-federation-v1-state-ids-roomid) + +use ruma_api::ruma_api; +use ruma_identifiers::{EventId, RoomId}; + +ruma_api! { + metadata: { + description: "Retrieves a snapshot of a room's state at a given event, in the form of event IDs", + method: GET, + name: "get_room_state_ids", + path: "/_matrix/federation/v1/state_ids/:room_id", + rate_limited: false, + requires_authentication: true, + } + + #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] + request: { + /// The room ID to get state for. + #[ruma_api(path)] + pub room_id: &'a RoomId, + + /// An event ID in the room to retrieve the state at. + #[ruma_api(query)] + pub event_id: &'a EventId, + } + + #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] + response: { + /// The full set of authorization events that make up the state of the + /// room, and their authorization events, recursively. + pub auth_chain_ids: Vec, + + /// The fully resolved state of the room at the given event. + pub pdu_ids: Vec, + } +} + +impl<'a> Request<'a> { + /// Creates a new `Request` with the given event id and room id. + pub fn new(event_id: &'a EventId, room_id: &'a RoomId) -> Self { + Self { event_id, room_id } + } +} + +impl Response { + /// Creates a new `Response` with the given auth chain IDs and room state IDs. + pub fn new(auth_chain_ids: Vec, pdu_ids: Vec) -> Self { + Self { auth_chain_ids, pdu_ids } + } +} diff --git a/ruma-serde/src/lib.rs b/ruma-serde/src/lib.rs index 18132537..165c33df 100644 --- a/ruma-serde/src/lib.rs +++ b/ruma-serde/src/lib.rs @@ -6,6 +6,7 @@ pub mod can_be_empty; pub mod duration; pub mod empty; pub mod json_string; +pub mod single_element_seq; pub mod test; pub mod time; pub mod urlencoded; diff --git a/ruma-serde/src/single_element_seq.rs b/ruma-serde/src/single_element_seq.rs new file mode 100644 index 00000000..940593a1 --- /dev/null +++ b/ruma-serde/src/single_element_seq.rs @@ -0,0 +1,22 @@ +//! De-/serialization functions to and from single element sequences. + +use serde::{ + de::{Deserialize, Deserializer}, + ser::{Serialize, Serializer}, +}; + +pub fn serialize(element: &T, serializer: S) -> Result +where + T: Serialize, + S: Serializer, +{ + [element].serialize(serializer) +} + +pub fn deserialize<'de, T, D>(deserializer: D) -> Result +where + T: Deserialize<'de>, + D: Deserializer<'de>, +{ + <[_; 1]>::deserialize(deserializer).map(|[first]| first) +}