ruma_federation_api/
space.rs

1//! Spaces endpoints.
2
3use ruma_common::{
4    room::RoomSummary,
5    serde::{from_raw_json_value, Raw},
6};
7use ruma_events::space::child::HierarchySpaceChildEvent;
8use serde::{Deserialize, Serialize};
9use serde_json::value::RawValue as RawJsonValue;
10
11pub mod get_hierarchy;
12
13/// The summary of a parent space.
14#[derive(Clone, Debug, Serialize)]
15#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
16pub struct SpaceHierarchyParentSummary {
17    /// The summary of the room.
18    #[serde(flatten)]
19    pub summary: RoomSummary,
20
21    /// The stripped `m.space.child` events of the space.
22    ///
23    /// If the room is not a space, this should be empty.
24    pub children_state: Vec<Raw<HierarchySpaceChildEvent>>,
25}
26
27impl SpaceHierarchyParentSummary {
28    /// Construct a `SpaceHierarchyRoomsChunk` with the given summary and children state.
29    pub fn new(summary: RoomSummary, children_state: Vec<Raw<HierarchySpaceChildEvent>>) -> Self {
30        Self { summary, children_state }
31    }
32}
33
34impl<'de> Deserialize<'de> for SpaceHierarchyParentSummary {
35    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36    where
37        D: serde::Deserializer<'de>,
38    {
39        #[derive(Deserialize)]
40        struct SpaceHierarchyRoomsChunkDeHelper {
41            children_state: Vec<Raw<HierarchySpaceChildEvent>>,
42        }
43
44        let json = Box::<RawJsonValue>::deserialize(deserializer)?;
45        let summary: RoomSummary = from_raw_json_value(&json)?;
46        let SpaceHierarchyRoomsChunkDeHelper { children_state } = from_raw_json_value(&json)?;
47
48        Ok(Self { summary, children_state })
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use serde_json::{from_value as from_json_value, json};
55
56    use super::SpaceHierarchyParentSummary;
57
58    #[test]
59    fn deserialize_space_hierarchy_rooms_chunk() {
60        let json = json!({
61            "room_id": "!room:localhost",
62            "num_joined_members": 5,
63            "world_readable": false,
64            "guest_can_join": false,
65            "join_rule": "restricted",
66            "allowed_room_ids": ["!otherroom:localhost"],
67            "children_state": [
68                {
69                    "content": {
70                        "via": [
71                            "example.org"
72                        ]
73                    },
74                    "origin_server_ts": 1_629_413_349,
75                    "sender": "@alice:example.org",
76                    "state_key": "!a:example.org",
77                    "type": "m.space.child"
78                }
79            ],
80        });
81
82        let room = from_json_value::<SpaceHierarchyParentSummary>(json).unwrap();
83        assert_eq!(room.summary.room_id, "!room:localhost");
84        let space_child = room.children_state[0].deserialize().unwrap();
85        assert_eq!(space_child.state_key, "!a:example.org");
86    }
87}