Skip to main content

ruma_client_api/membership/
joined_members.rs

1//! `GET /_matrix/client/*/rooms/{roomId}/joined_members`
2//!
3//! Get a map of user IDs to member info objects for members of the room. Primarily for use in
4//! Application Services.
5
6pub mod v3 {
7    //! `/v3/` ([spec])
8    //!
9    //! [spec]: https://spec.matrix.org/v1.19/client-server-api/#get_matrixclientv3roomsroomidjoined_members
10
11    use std::collections::BTreeMap;
12
13    use ruma_common::{
14        OwnedMxcUri, OwnedRoomId, OwnedUserId,
15        api::{auth_scheme::AccessToken, request, response},
16        metadata,
17    };
18    use serde::{Deserialize, Serialize};
19
20    metadata! {
21        method: GET,
22        rate_limited: false,
23        authentication: AccessToken,
24        history: {
25            1.0 => "/_matrix/client/r0/rooms/{room_id}/joined_members",
26            1.1 => "/_matrix/client/v3/rooms/{room_id}/joined_members",
27        }
28    }
29
30    /// Request type for the `joined_members` endpoint.
31    #[request]
32    pub struct Request {
33        /// The room to get the members of.
34        #[ruma_api(path)]
35        pub room_id: OwnedRoomId,
36    }
37
38    /// Response type for the `joined_members` endpoint.
39    #[response]
40    pub struct Response {
41        /// A map from user ID to information about each user with joined membership in the room.
42        pub joined: BTreeMap<OwnedUserId, RoomMember>,
43    }
44
45    impl Request {
46        /// Creates a new `Request` with the given room ID.
47        pub fn new(room_id: OwnedRoomId) -> Self {
48            Self { room_id }
49        }
50    }
51
52    impl Response {
53        /// Creates a new `Response` with the given joined rooms.
54        pub fn new(joined: BTreeMap<OwnedUserId, RoomMember>) -> Self {
55            Self { joined }
56        }
57    }
58
59    /// Information about a room member.
60    #[derive(Clone, Debug, Default, Deserialize, Serialize)]
61    #[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
62    pub struct RoomMember {
63        /// The display name of the user.
64        #[serde(skip_serializing_if = "Option::is_none")]
65        pub display_name: Option<String>,
66
67        /// The mxc avatar url of the user.
68        ///
69        /// If you activate the `compat-empty-string-null` feature, this field being an empty
70        /// string in JSON will result in `None` here during deserialization.
71        #[serde(skip_serializing_if = "Option::is_none")]
72        #[cfg_attr(
73            feature = "compat-empty-string-null",
74            serde(default, deserialize_with = "ruma_common::serde::empty_string_as_none")
75        )]
76        pub avatar_url: Option<OwnedMxcUri>,
77    }
78
79    impl RoomMember {
80        /// Creates an empty `RoomMember`.
81        pub fn new() -> Self {
82            Default::default()
83        }
84    }
85
86    #[cfg(test)]
87    mod tests {
88        use serde_json::{from_value as from_json_value, json};
89        use strass::assert_variant_eq;
90
91        use super::RoomMember;
92
93        #[test]
94        fn deserialize_room_member() {
95            let member = from_json_value::<RoomMember>(json!({
96                "display_name": "alice",
97                "avatar_url": "mxc://localhost/wefuiwegh8742w",
98            }))
99            .unwrap();
100            assert_eq!(member.display_name.as_deref(), Some("alice"));
101            assert_variant_eq!(member.avatar_url, Some("mxc://localhost/wefuiwegh8742w"));
102
103            #[cfg(feature = "compat-empty-string-null")]
104            {
105                let member = from_json_value::<RoomMember>(json!({
106                    "display_name": "alice",
107                    "avatar_url": "",
108                }))
109                .unwrap();
110                assert_eq!(member.display_name.as_deref(), Some("alice"));
111                assert_eq!(member.avatar_url, None);
112            }
113        }
114    }
115}