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