ruma_client_api/
space.rs

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