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
//! [PUT /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-profile-userid-avatar-url)

use ruma_api::ruma_api;
use ruma_identifiers::{MxcUri, UserId};

ruma_api! {
    metadata: {
        description: "Set the avatar URL of the user.",
        method: PUT,
        name: "set_avatar_url",
        path: "/_matrix/client/r0/profile/:user_id/avatar_url",
        rate_limited: true,
        authentication: AccessToken,
    }

    request: {
        /// The user whose avatar URL will be set.
        #[ruma_api(path)]
        pub user_id: &'a UserId,

        /// The new avatar URL for the user.
        ///
        /// `None` is used to unset the avatar.
        ///
        /// If you activate the `compat` feature, this field being an empty string in JSON will result
        /// in `None` here during deserialization.
        #[cfg_attr(
            feature = "compat",
            serde(
                default,
                deserialize_with = "ruma_serde::empty_string_as_none",
                serialize_with = "ruma_serde::none_as_empty_string"
            )
        )]
        #[cfg_attr(
            not(feature = "compat"),
            serde(skip_serializing_if = "Option::is_none")
        )]
        pub avatar_url: Option<&'a MxcUri>,

        /// 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-doc/pull/2448).
        #[cfg(feature = "unstable-pre-spec")]
        #[serde(rename = "xyz.amorgan.blurhash", skip_serializing_if = "Option::is_none")]
        pub blurhash: Option<&'a str>,
    }

    #[derive(Default)]
    response: {}

    error: crate::Error
}

impl<'a> Request<'a> {
    /// Creates a new `Request` with the given user ID and avatar URL.
    pub fn new(user_id: &'a UserId, avatar_url: Option<&'a MxcUri>) -> Self {
        Self {
            user_id,
            avatar_url,
            #[cfg(feature = "unstable-pre-spec")]
            blurhash: None,
        }
    }
}

impl Response {
    /// Creates an empty `Response`.
    pub fn new() -> Self {
        Self {}
    }
}

#[cfg(all(test, feature = "server"))]
mod tests {
    use matches::assert_matches;
    use ruma_api::IncomingRequest as _;

    use super::IncomingRequest;

    #[test]
    fn deserialize_unset_request() {
        assert_matches!(
            IncomingRequest::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(),
            ).unwrap(),
            IncomingRequest { user_id, avatar_url: None, .. } if user_id == "@foo:bar.org"
        );

        #[cfg(feature = "compat")]
        assert_matches!(
            IncomingRequest::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(),
            ).unwrap(),
            IncomingRequest { user_id, avatar_url: None, .. } if user_id == "@foo:bar.org"
        );
    }
}