ruma_client_api/membership/
get_member_events.rs

1//! `GET /_matrix/client/*/rooms/{roomId}/members`
2//!
3//! Get membership events for a room.
4
5pub mod v3 {
6    //! `/v3/` ([spec])
7    //!
8    //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3roomsroomidmembers
9
10    use ruma_common::{
11        api::{request, response, Metadata},
12        metadata,
13        serde::Raw,
14        OwnedRoomId,
15    };
16    use ruma_events::room::member::{MembershipState, RoomMemberEvent};
17
18    const METADATA: Metadata = metadata! {
19        method: GET,
20        rate_limited: false,
21        authentication: AccessToken,
22        history: {
23            1.0 => "/_matrix/client/r0/rooms/{room_id}/members",
24            1.1 => "/_matrix/client/v3/rooms/{room_id}/members",
25        }
26    };
27
28    /// Request type for the `get_member_events` endpoint.
29    #[request(error = crate::Error)]
30    pub struct Request {
31        /// The room to get the member events for.
32        #[ruma_api(path)]
33        pub room_id: OwnedRoomId,
34
35        /// The point in time (pagination token) to return members for in the room.
36        ///
37        /// This token can be obtained from a prev_batch token returned for each room by the sync
38        /// API.
39        #[serde(skip_serializing_if = "Option::is_none")]
40        #[ruma_api(query)]
41        pub at: Option<String>,
42
43        /// The kind of memberships to filter for.
44        ///
45        /// Defaults to no filtering if unspecified. When specified alongside not_membership, the
46        /// two parameters create an 'or' condition: either the membership is the same as
47        /// membership or is not the same as not_membership.
48        #[serde(skip_serializing_if = "Option::is_none")]
49        #[ruma_api(query)]
50        pub membership: Option<MembershipState>,
51
52        /// The kind of memberships to *exclude* from the results.
53        ///
54        /// Defaults to no filtering if unspecified.
55        #[serde(skip_serializing_if = "Option::is_none")]
56        #[ruma_api(query)]
57        pub not_membership: Option<MembershipState>,
58    }
59
60    /// Response type for the `get_member_events` endpoint.
61    #[response(error = crate::Error)]
62    pub struct Response {
63        /// A list of member events.
64        pub chunk: Vec<Raw<RoomMemberEvent>>,
65    }
66
67    impl Request {
68        /// Creates a new `Request` with the given room ID.
69        pub fn new(room_id: OwnedRoomId) -> Self {
70            Self { room_id, at: None, membership: None, not_membership: None }
71        }
72    }
73
74    impl Response {
75        /// Creates a new `Response` with the given member event chunk.
76        pub fn new(chunk: Vec<Raw<RoomMemberEvent>>) -> Self {
77            Self { chunk }
78        }
79    }
80
81    #[cfg(all(test, feature = "server"))]
82    mod tests {
83        use ruma_common::api::IncomingRequest as _;
84
85        use super::{MembershipState, Request};
86
87        #[test]
88        fn deserialization() {
89            let uri = http::Uri::builder()
90                .scheme("https")
91                .authority("example.org")
92                .path_and_query(
93                    "/_matrix/client/r0/rooms/!dummy%3Aexample.org/members\
94                     ?not_membership=leave\
95                     &at=1026",
96                )
97                .build()
98                .unwrap();
99
100            let req = Request::try_from_http_request(
101                http::Request::builder().uri(uri).body(&[] as &[u8]).unwrap(),
102                &["!dummy:example.org"],
103            )
104            .unwrap();
105
106            assert_eq!(req.room_id, "!dummy:example.org");
107            assert_eq!(req.at.as_deref(), Some("1026"));
108            assert_eq!(req.membership, None);
109            assert_eq!(req.not_membership, Some(MembershipState::Leave));
110        }
111    }
112}