1
0
Fork 0
forked from mirror/grapevine

enable doc_markdown lint

This commit is contained in:
Charles Hall 2024-05-14 16:34:10 -07:00
parent 0f2cf26a36
commit da440934bd
No known key found for this signature in database
GPG key ID: 7B8E0645816E07CF
21 changed files with 51 additions and 46 deletions

View file

@ -24,6 +24,7 @@ dbg_macro = "warn"
default_trait_access = "warn" default_trait_access = "warn"
default_union_representation = "warn" default_union_representation = "warn"
deref_by_slicing = "warn" deref_by_slicing = "warn"
doc_markdown = "warn"
empty_drop = "warn" empty_drop = "warn"
empty_structs_with_brackets = "warn" empty_structs_with_brackets = "warn"
error_impl_error = "warn" error_impl_error = "warn"

4
clippy.toml Normal file
View file

@ -0,0 +1,4 @@
doc-valid-idents = [
"SemVer",
"..",
]

View file

@ -69,11 +69,11 @@ pub(crate) async fn get_register_available_route(
/// to check if the user id is valid and available. /// to check if the user id is valid and available.
/// ///
/// - Only works if registration is enabled /// - Only works if registration is enabled
/// - If type is guest: ignores all parameters except initial_device_display_name /// - If type is guest: ignores all parameters except `initial_device_display_name`
/// - If sender is not appservice: Requires UIAA (but we only use a dummy stage) /// - If sender is not appservice: Requires UIAA (but we only use a dummy stage)
/// - If type is not guest and no username is given: Always fails after UIAA check /// - If type is not guest and no username is given: Always fails after UIAA check
/// - Creates a new account and populates it with default account data /// - Creates a new account and populates it with default account data
/// - If `inhibit_login` is false: Creates a device and returns device id and access_token /// - If `inhibit_login` is false: Creates a device and returns `device_id` and `access_token`
pub(crate) async fn register_route( pub(crate) async fn register_route(
body: Ruma<register::v3::Request>, body: Ruma<register::v3::Request>,
) -> Result<register::v3::Response> { ) -> Result<register::v3::Response> {
@ -304,9 +304,9 @@ pub(crate) async fn register_route(
/// - The password hash is calculated using argon2 with 32 character salt, the plain password is /// - The password hash is calculated using argon2 with 32 character salt, the plain password is
/// not saved /// not saved
/// ///
/// If logout_devices is true it does the following for each device except the sender device: /// If `logout_devices` is true it does the following for each device except the sender device:
/// - Invalidates access token /// - Invalidates access token
/// - Deletes device metadata (device id, device display name, last seen ip, last seen ts) /// - Deletes device metadata (device ID, device display name, last seen IP, last seen timestamp)
/// - Forgets to-device events /// - Forgets to-device events
/// - Triggers device list updates /// - Triggers device list updates
pub(crate) async fn change_password_route( pub(crate) async fn change_password_route(
@ -372,7 +372,7 @@ pub(crate) async fn change_password_route(
/// # `GET _matrix/client/r0/account/whoami` /// # `GET _matrix/client/r0/account/whoami`
/// ///
/// Get user_id of the sender user. /// Get `user_id` of the sender user.
/// ///
/// Note: Also works for Application Services /// Note: Also works for Application Services
pub(crate) async fn whoami_route(body: Ruma<whoami::v3::Request>) -> Result<whoami::v3::Response> { pub(crate) async fn whoami_route(body: Ruma<whoami::v3::Request>) -> Result<whoami::v3::Response> {

View file

@ -12,7 +12,7 @@ use tracing::error;
/// Allows loading room history around an event. /// Allows loading room history around an event.
/// ///
/// - Only works if the user is joined (TODO: always allow, but only show events if the user was /// - Only works if the user is joined (TODO: always allow, but only show events if the user was
/// joined, depending on history_visibility) /// joined, depending on `history_visibility`)
pub(crate) async fn get_context_route( pub(crate) async fn get_context_route(
body: Ruma<get_context::v3::Request>, body: Ruma<get_context::v3::Request>,
) -> Result<get_context::v3::Response> { ) -> Result<get_context::v3::Response> {

View file

@ -111,7 +111,7 @@ pub(crate) async fn send_message_event_route(
/// Allows paginating through room history. /// Allows paginating through room history.
/// ///
/// - Only works if the user is joined (TODO: always allow, but only show events where the user was /// - Only works if the user is joined (TODO: always allow, but only show events where the user was
/// joined, depending on history_visibility) /// joined, depending on `history_visibility`)
pub(crate) async fn get_message_events_route( pub(crate) async fn get_message_events_route(
body: Ruma<get_message_events::v3::Request>, body: Ruma<get_message_events::v3::Request>,
) -> Result<get_message_events::v3::Response> { ) -> Result<get_message_events::v3::Response> {

View file

@ -130,7 +130,7 @@ pub(crate) async fn get_displayname_route(
/// # `PUT /_matrix/client/r0/profile/{userId}/avatar_url` /// # `PUT /_matrix/client/r0/profile/{userId}/avatar_url`
/// ///
/// Updates the avatar_url and blurhash. /// Updates the `avatar_url` and `blurhash`.
/// ///
/// - Also makes sure other users receive the update using presence EDUs /// - Also makes sure other users receive the update using presence EDUs
pub(crate) async fn set_avatar_url_route( pub(crate) async fn set_avatar_url_route(
@ -217,9 +217,9 @@ pub(crate) async fn set_avatar_url_route(
/// # `GET /_matrix/client/r0/profile/{userId}/avatar_url` /// # `GET /_matrix/client/r0/profile/{userId}/avatar_url`
/// ///
/// Returns the avatar_url and blurhash of the user. /// Returns the `avatar_url` and `blurhash` of the user.
/// ///
/// - If user is on another server: Fetches avatar_url and blurhash over federation /// - If user is on another server: Fetches `avatar_url` and `blurhash` over federation
pub(crate) async fn get_avatar_url_route( pub(crate) async fn get_avatar_url_route(
body: Ruma<get_avatar_url::v3::Request>, body: Ruma<get_avatar_url::v3::Request>,
) -> Result<get_avatar_url::v3::Response> { ) -> Result<get_avatar_url::v3::Response> {
@ -249,7 +249,7 @@ pub(crate) async fn get_avatar_url_route(
/// # `GET /_matrix/client/r0/profile/{userId}` /// # `GET /_matrix/client/r0/profile/{userId}`
/// ///
/// Returns the displayname, avatar_url and blurhash of the user. /// Returns the `displayname`, `avatar_url` and `blurhash` of the user.
/// ///
/// - If user is on another server: Fetches profile over federation /// - If user is on another server: Fetches profile over federation
pub(crate) async fn get_profile_route( pub(crate) async fn get_profile_route(

View file

@ -34,7 +34,7 @@ use tracing::{info, warn};
/// Creates a new room. /// Creates a new room.
/// ///
/// - Room ID is randomly generated /// - Room ID is randomly generated
/// - Create alias if room_alias_name is set /// - Create alias if `room_alias_name` is set
/// - Send create event /// - Send create event
/// - Join sender user /// - Join sender user
/// - Send power levels event /// - Send power levels event
@ -543,7 +543,7 @@ pub(crate) async fn get_room_event_route(
/// ///
/// Lists all aliases of the room. /// Lists all aliases of the room.
/// ///
/// - Only users joined to the room are allowed to call this TODO: Allow any user to call it if history_visibility is world readable /// - Only users joined to the room are allowed to call this TODO: Allow any user to call it if `history_visibility` is world readable
pub(crate) async fn get_room_aliases_route( pub(crate) async fn get_room_aliases_route(
body: Ruma<aliases::v3::Request>, body: Ruma<aliases::v3::Request>,
) -> Result<aliases::v3::Response> { ) -> Result<aliases::v3::Response> {

View file

@ -1,7 +1,7 @@
use crate::{services, Result, Ruma}; use crate::{services, Result, Ruma};
use ruma::{api::client::space::get_hierarchy, uint}; use ruma::{api::client::space::get_hierarchy, uint};
/// # `GET /_matrix/client/v1/rooms/{room_id}/hierarchy`` /// # `GET /_matrix/client/v1/rooms/{room_id}/hierarchy`
/// ///
/// Paginates over the space tree in a depth-first manner to locate child rooms of a given space. /// Paginates over the space tree in a depth-first manner to locate child rooms of a given space.
pub(crate) async fn get_hierarchy_route( pub(crate) async fn get_hierarchy_route(

View file

@ -20,7 +20,7 @@ use tracing::log::warn;
/// ///
/// - The only requirement for the content is that it has to be valid json /// - The only requirement for the content is that it has to be valid json
/// - Tries to send the event into the room, auth rules will determine if it is allowed /// - Tries to send the event into the room, auth rules will determine if it is allowed
/// - If event is new canonical_alias: Rejects if alias is incorrect /// - If event is new `canonical_alias`: Rejects if alias is incorrect
pub(crate) async fn send_state_event_for_key_route( pub(crate) async fn send_state_event_for_key_route(
body: Ruma<send_state_event::v3::Request>, body: Ruma<send_state_event::v3::Request>,
) -> Result<send_state_event::v3::Response> { ) -> Result<send_state_event::v3::Response> {
@ -45,7 +45,7 @@ pub(crate) async fn send_state_event_for_key_route(
/// ///
/// - The only requirement for the content is that it has to be valid json /// - The only requirement for the content is that it has to be valid json
/// - Tries to send the event into the room, auth rules will determine if it is allowed /// - Tries to send the event into the room, auth rules will determine if it is allowed
/// - If event is new canonical_alias: Rejects if alias is incorrect /// - If event is new `canonical_alias`: Rejects if alias is incorrect
pub(crate) async fn send_state_event_for_empty_key_route( pub(crate) async fn send_state_event_for_empty_key_route(
body: Ruma<send_state_event::v3::Request>, body: Ruma<send_state_event::v3::Request>,
) -> Result<RumaResponse<send_state_event::v3::Response>> { ) -> Result<RumaResponse<send_state_event::v3::Response>> {

View file

@ -46,8 +46,8 @@ use tracing::{debug, error, info};
/// ///
/// Calling this endpoint with a `since` parameter from a previous `next_batch` returns: /// Calling this endpoint with a `since` parameter from a previous `next_batch` returns:
/// For joined rooms: /// For joined rooms:
/// - Some of the most recent events of each timeline that happened after since /// - Some of the most recent events of each timeline that happened after `since`
/// - If user joined the room after since: All state events (unless lazy loading is activated) and /// - If user joined the room after `since`: All state events (unless lazy loading is activated) and
/// all device list updates in that room /// all device list updates in that room
/// - If the user was already in the room: A list of all events that are in the state now, but were /// - If the user was already in the room: A list of all events that are in the state now, but were
/// not in the state at `since` /// not in the state at `since`
@ -61,7 +61,7 @@ use tracing::{debug, error, info};
/// - If the user was invited after `since`: A subset of the state of the room at the point of the invite /// - If the user was invited after `since`: A subset of the state of the room at the point of the invite
/// ///
/// For left rooms: /// For left rooms:
/// - If the user left after `since`: prev_batch token, empty state (TODO: subset of the state at the point of the leave) /// - If the user left after `since`: `prev_batch` token, empty state (TODO: subset of the state at the point of the leave)
/// ///
/// - Sync is handled in an async task, multiple requests from the same device with the same /// - Sync is handled in an async task, multiple requests from the same device with the same
/// `since` will be cached /// `since` will be cached

View file

@ -61,8 +61,8 @@ use tracing::{debug, error, warn};
/// Wraps either an literal IP address plus port, or a hostname plus complement /// Wraps either an literal IP address plus port, or a hostname plus complement
/// (colon-plus-port if it was specified). /// (colon-plus-port if it was specified).
/// ///
/// Note: A `FedDest::Named` might contain an IP address in string form if there /// Note: A [`FedDest::Named`] might contain an IP address in string form if there
/// was no port specified to construct a SocketAddr with. /// was no port specified to construct a [`SocketAddr`] with.
/// ///
/// # Examples: /// # Examples:
/// ```rust /// ```rust
@ -340,7 +340,7 @@ fn add_port_to_hostname(destination_str: &str) -> FedDest {
FedDest::Named(host.to_owned(), port.to_owned()) FedDest::Named(host.to_owned(), port.to_owned())
} }
/// Returns: actual_destination, host header /// Returns: `actual_destination`, `Host` header
/// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names> /// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
/// Numbers in comments below refer to bullet points in linked section of specification /// Numbers in comments below refer to bullet points in linked section of specification
async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDest) { async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDest) {

View file

@ -175,7 +175,7 @@ impl service::rooms::short::Data for KeyValueDatabase {
Ok(result) Ok(result)
} }
/// Returns (shortstatehash, already_existed) /// Returns `(shortstatehash, already_existed)`
fn get_or_create_shortstatehash(&self, state_hash: &[u8]) -> Result<(u64, bool)> { fn get_or_create_shortstatehash(&self, state_hash: &[u8]) -> Result<(u64, bool)> {
Ok(match self.statehash_shortstatehash.get(state_hash)? { Ok(match self.statehash_shortstatehash.get(state_hash)? {
Some(shortstatehash) => ( Some(shortstatehash) => (

View file

@ -118,7 +118,7 @@ impl service::users::Data for KeyValueDatabase {
} }
} }
/// Returns the displayname of a user on this homeserver. /// Returns the `displayname` of a user on this homeserver.
fn displayname(&self, user_id: &UserId) -> Result<Option<String>> { fn displayname(&self, user_id: &UserId) -> Result<Option<String>> {
self.userid_displayname self.userid_displayname
.get(user_id.as_bytes())? .get(user_id.as_bytes())?
@ -129,7 +129,7 @@ impl service::users::Data for KeyValueDatabase {
}) })
} }
/// Sets a new displayname or removes it if displayname is None. You still need to nofify all rooms of this change. /// Sets a new `displayname` or removes it if `displayname` is `None`. You still need to nofify all rooms of this change.
fn set_displayname(&self, user_id: &UserId, displayname: Option<String>) -> Result<()> { fn set_displayname(&self, user_id: &UserId, displayname: Option<String>) -> Result<()> {
if let Some(displayname) = displayname { if let Some(displayname) = displayname {
self.userid_displayname self.userid_displayname
@ -141,7 +141,7 @@ impl service::users::Data for KeyValueDatabase {
Ok(()) Ok(())
} }
/// Get the avatar_url of a user. /// Get the `avatar_url` of a user.
fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>> { fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>> {
self.userid_avatarurl self.userid_avatarurl
.get(user_id.as_bytes())? .get(user_id.as_bytes())?
@ -153,7 +153,7 @@ impl service::users::Data for KeyValueDatabase {
.transpose() .transpose()
} }
/// Sets a new avatar_url or removes it if avatar_url is None. /// Sets a new `avatar_url` or removes it if `avatar_url` is `None`.
fn set_avatar_url(&self, user_id: &UserId, avatar_url: Option<OwnedMxcUri>) -> Result<()> { fn set_avatar_url(&self, user_id: &UserId, avatar_url: Option<OwnedMxcUri>) -> Result<()> {
if let Some(avatar_url) = avatar_url { if let Some(avatar_url) = avatar_url {
self.userid_avatarurl self.userid_avatarurl
@ -165,7 +165,7 @@ impl service::users::Data for KeyValueDatabase {
Ok(()) Ok(())
} }
/// Get the blurhash of a user. /// Get the `blurhash` of a user.
fn blurhash(&self, user_id: &UserId) -> Result<Option<String>> { fn blurhash(&self, user_id: &UserId) -> Result<Option<String>> {
self.userid_blurhash self.userid_blurhash
.get(user_id.as_bytes())? .get(user_id.as_bytes())?
@ -178,7 +178,7 @@ impl service::users::Data for KeyValueDatabase {
.transpose() .transpose()
} }
/// Sets a new avatar_url or removes it if avatar_url is None. /// Sets a new `avatar_url` or removes it if `avatar_url` is `None`.
fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()> { fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()> {
if let Some(blurhash) = blurhash { if let Some(blurhash) = blurhash {
self.userid_blurhash self.userid_blurhash
@ -954,7 +954,7 @@ impl service::users::Data for KeyValueDatabase {
/// Will only return with Some(username) if the password was not empty and the /// Will only return with Some(username) if the password was not empty and the
/// username could be successfully parsed. /// username could be successfully parsed.
/// If utils::string_from_bytes(...) returns an error that username will be skipped /// If [`utils::string_from_bytes`] returns an error that username will be skipped
/// and the error will be logged. /// and the error will be logged.
fn get_username_with_valid_password(username: &[u8], password: &[u8]) -> Option<String> { fn get_username_with_valid_password(username: &[u8], password: &[u8]) -> Option<String> {
// A valid password is not empty // A valid password is not empty

View file

@ -10,7 +10,7 @@ pub(crate) trait Data: Send + Sync {
content_type: Option<&str>, content_type: Option<&str>,
) -> Result<Vec<u8>>; ) -> Result<Vec<u8>>;
/// Returns content_disposition, content_type and the metadata key. /// Returns `content_disposition`, `content_type` and the `metadata` key.
fn search_file_metadata( fn search_file_metadata(
&self, &self,
mxc: String, mxc: String,

View file

@ -10,7 +10,7 @@ pub(crate) trait Data: Send + Sync {
event: ReceiptEvent, event: ReceiptEvent,
) -> Result<()>; ) -> Result<()>;
/// Returns an iterator over the most recent read_receipts in a room that happened after the event with id `since`. /// Returns an iterator over the most recent read receipts in a room that happened after the event with id `since`.
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
fn readreceipts_since<'a>( fn readreceipts_since<'a>(
&'a self, &'a self,

View file

@ -12,7 +12,7 @@ pub(crate) struct Service {
} }
impl Service { impl Service {
/// Sets a user as typing until the timeout timestamp is reached or roomtyping_remove is /// Sets a user as typing until the timeout timestamp is reached or `roomtyping_remove` is
/// called. /// called.
pub(crate) async fn typing_add( pub(crate) async fn typing_add(
&self, &self,

View file

@ -42,7 +42,7 @@ impl Service {
self.db.get_statekey_from_short(shortstatekey) self.db.get_statekey_from_short(shortstatekey)
} }
/// Returns (shortstatehash, already_existed) /// Returns `(shortstatehash, already_existed)`
pub(crate) fn get_or_create_shortstatehash(&self, state_hash: &[u8]) -> Result<(u64, bool)> { pub(crate) fn get_or_create_shortstatehash(&self, state_hash: &[u8]) -> Result<(u64, bool)> {
self.db.get_or_create_shortstatehash(state_hash) self.db.get_or_create_shortstatehash(state_hash)
} }

View file

@ -22,7 +22,7 @@ pub(crate) trait Data: Send + Sync {
fn get_statekey_from_short(&self, shortstatekey: u64) -> Result<(StateEventType, String)>; fn get_statekey_from_short(&self, shortstatekey: u64) -> Result<(StateEventType, String)>;
/// Returns (shortstatehash, already_existed) /// Returns `(shortstatehash, already_existed)`
fn get_or_create_shortstatehash(&self, state_hash: &[u8]) -> Result<(u64, bool)>; fn get_or_create_shortstatehash(&self, state_hash: &[u8]) -> Result<(u64, bool)>;
fn get_shortroomid(&self, room_id: &RoomId) -> Result<Option<u64>>; fn get_shortroomid(&self, room_id: &RoomId) -> Result<Option<u64>>;

View file

@ -7,7 +7,7 @@ pub(crate) trait Data: Send + Sync {
/// Returns the last state hash key added to the db for the given room. /// Returns the last state hash key added to the db for the given room.
fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>>; fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>>;
/// Set the state hash to a new version, but does not update state_cache. /// Set the state hash to a new version, but does not update `state_cache`.
fn set_room_state( fn set_room_state(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
@ -18,7 +18,7 @@ pub(crate) trait Data: Send + Sync {
/// Associates a state with an event. /// Associates a state with an event.
fn set_event_state(&self, shorteventid: u64, shortstatehash: u64) -> Result<()>; fn set_event_state(&self, shorteventid: u64, shortstatehash: u64) -> Result<()>;
/// Returns all events we would send as the prev_events of the next event. /// Returns all events we would send as the `prev_events` of the next event.
fn get_forward_extremities(&self, room_id: &RoomId) -> Result<HashSet<Arc<EventId>>>; fn get_forward_extremities(&self, room_id: &RoomId) -> Result<HashSet<Arc<EventId>>>;
/// Replace the forward extremities of the room. /// Replace the forward extremities of the room.

View file

@ -327,12 +327,12 @@ impl Service {
self.db.set_displayname(user_id, displayname) self.db.set_displayname(user_id, displayname)
} }
/// Get the avatar_url of a user. /// Get the `avatar_url` of a user.
pub(crate) fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>> { pub(crate) fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>> {
self.db.avatar_url(user_id) self.db.avatar_url(user_id)
} }
/// Sets a new avatar_url or removes it if avatar_url is None. /// Sets a new `avatar_url` or removes it if `avatar_url` is `None`.
pub(crate) fn set_avatar_url( pub(crate) fn set_avatar_url(
&self, &self,
user_id: &UserId, user_id: &UserId,
@ -341,12 +341,12 @@ impl Service {
self.db.set_avatar_url(user_id, avatar_url) self.db.set_avatar_url(user_id, avatar_url)
} }
/// Get the blurhash of a user. /// Get the `blurhash` of a user.
pub(crate) fn blurhash(&self, user_id: &UserId) -> Result<Option<String>> { pub(crate) fn blurhash(&self, user_id: &UserId) -> Result<Option<String>> {
self.db.blurhash(user_id) self.db.blurhash(user_id)
} }
/// Sets a new avatar_url or removes it if avatar_url is None. /// Sets a new `avatar_url` or removes it if `avatar_url` is `None`.
pub(crate) fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()> { pub(crate) fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()> {
self.db.set_blurhash(user_id, blurhash) self.db.set_blurhash(user_id, blurhash)
} }

View file

@ -39,19 +39,19 @@ pub(crate) trait Data: Send + Sync {
/// Returns the displayname of a user on this homeserver. /// Returns the displayname of a user on this homeserver.
fn displayname(&self, user_id: &UserId) -> Result<Option<String>>; fn displayname(&self, user_id: &UserId) -> Result<Option<String>>;
/// Sets a new displayname or removes it if displayname is None. You still need to nofify all rooms of this change. /// Sets a new `displayname` or removes it if `displayname` is `None`. You still need to nofify all rooms of this change.
fn set_displayname(&self, user_id: &UserId, displayname: Option<String>) -> Result<()>; fn set_displayname(&self, user_id: &UserId, displayname: Option<String>) -> Result<()>;
/// Get the avatar_url of a user. /// Get the `avatar_url` of a user.
fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>>; fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>>;
/// Sets a new avatar_url or removes it if avatar_url is None. /// Sets a new `avatar_url` or removes it if `avatar_url` is `None`.
fn set_avatar_url(&self, user_id: &UserId, avatar_url: Option<OwnedMxcUri>) -> Result<()>; fn set_avatar_url(&self, user_id: &UserId, avatar_url: Option<OwnedMxcUri>) -> Result<()>;
/// Get the blurhash of a user. /// Get the `blurhash` of a user.
fn blurhash(&self, user_id: &UserId) -> Result<Option<String>>; fn blurhash(&self, user_id: &UserId) -> Result<Option<String>>;
/// Sets a new avatar_url or removes it if avatar_url is None. /// Sets a new `avatar_url` or removes it if `avatar_url` is `None`.
fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()>; fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()>;
/// Adds a new device to a user. /// Adds a new device to a user.