ruma_client_api/profile/
set_avatar_url.rs

1//! `PUT /_matrix/client/*/profile/{userId}/avatar_url`
2//!
3//! Set the avatar URL of the user.
4
5pub mod v3 {
6    //! `/v3/` ([spec])
7    //!
8    //! [spec]: https://spec.matrix.org/v1.15/client-server-api/#put_matrixclientv3profileuseridavatar_url
9
10    use ruma_common::{
11        OwnedMxcUri, OwnedUserId,
12        api::{auth_scheme::AccessToken, request, response},
13        metadata,
14    };
15
16    metadata! {
17        method: PUT,
18        rate_limited: true,
19        authentication: AccessToken,
20        history: {
21            1.0 => "/_matrix/client/r0/profile/{user_id}/avatar_url",
22            1.1 => "/_matrix/client/v3/profile/{user_id}/avatar_url",
23        }
24    }
25
26    /// Request type for the `set_avatar_url` endpoint.
27    #[request(error = crate::Error)]
28    pub struct Request {
29        /// The user whose avatar URL will be set.
30        #[ruma_api(path)]
31        pub user_id: OwnedUserId,
32
33        /// The new avatar URL for the user.
34        ///
35        /// `None` is used to unset the avatar.
36        ///
37        /// If you activate the `compat-empty-string-null` feature, this field being an empty
38        /// string in JSON will result in `None` here during deserialization.
39        ///
40        /// If you active the `compat-unset-avatar` feature, this field being `None` will result
41        /// in an empty string in serialization, which is the same thing Element Web does (c.f.
42        /// <https://github.com/matrix-org/matrix-spec/issues/378#issuecomment-1055831264>).
43        #[cfg_attr(
44            feature = "compat-empty-string-null",
45            serde(default, deserialize_with = "ruma_common::serde::empty_string_as_none")
46        )]
47        #[cfg_attr(
48            feature = "compat-unset-avatar",
49            serde(serialize_with = "ruma_common::serde::none_as_empty_string")
50        )]
51        #[cfg_attr(
52            not(feature = "compat-unset-avatar"),
53            serde(skip_serializing_if = "Option::is_none")
54        )]
55        pub avatar_url: Option<OwnedMxcUri>,
56
57        /// The [BlurHash](https://blurha.sh) for the avatar pointed to by `avatar_url`.
58        ///
59        /// This uses the unstable prefix in
60        /// [MSC2448](https://github.com/matrix-org/matrix-spec-proposals/pull/2448).
61        #[cfg(feature = "unstable-msc2448")]
62        #[serde(rename = "xyz.amorgan.blurhash", skip_serializing_if = "Option::is_none")]
63        pub blurhash: Option<String>,
64    }
65
66    /// Response type for the `set_avatar_url` endpoint.
67    #[response(error = crate::Error)]
68    #[derive(Default)]
69    pub struct Response {}
70
71    impl Request {
72        /// Creates a new `Request` with the given user ID and avatar URL.
73        #[deprecated = "Use the set_profile_field endpoint instead."]
74        pub fn new(user_id: OwnedUserId, avatar_url: Option<OwnedMxcUri>) -> Self {
75            Self {
76                user_id,
77                avatar_url,
78                #[cfg(feature = "unstable-msc2448")]
79                blurhash: None,
80            }
81        }
82    }
83
84    impl Response {
85        /// Creates an empty `Response`.
86        pub fn new() -> Self {
87            Self {}
88        }
89    }
90
91    #[cfg(all(test, feature = "server"))]
92    mod tests {
93        use ruma_common::api::IncomingRequest as _;
94
95        use super::Request;
96
97        #[test]
98        fn deserialize_unset_request() {
99            let req = Request::try_from_http_request(
100                http::Request::builder()
101                    .method("PUT")
102                    .uri("https://bar.org/_matrix/client/r0/profile/@foo:bar.org/avatar_url")
103                    .body(&[] as &[u8])
104                    .unwrap(),
105                &["@foo:bar.org"],
106            )
107            .unwrap();
108            assert_eq!(req.user_id, "@foo:bar.org");
109            assert_eq!(req.avatar_url, None);
110
111            #[cfg(feature = "compat-empty-string-null")]
112            {
113                let req = Request::try_from_http_request(
114                    http::Request::builder()
115                        .method("PUT")
116                        .uri("https://bar.org/_matrix/client/r0/profile/@foo:bar.org/avatar_url")
117                        .body(serde_json::to_vec(&serde_json::json!({ "avatar_url": "" })).unwrap())
118                        .unwrap(),
119                    &["@foo:bar.org"],
120                )
121                .unwrap();
122                assert_eq!(req.user_id, "@foo:bar.org");
123                assert_eq!(req.avatar_url, None);
124            }
125        }
126    }
127}