Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add role tags #1294

Merged
merged 4 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/model/guild/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use std::cmp::Ordering;

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
use async_trait::async_trait;
#[cfg(feature = "model")]
use serde::de::{Deserialize, Deserializer, Error as DeError};

#[cfg(feature = "model")]
use crate::builder::EditRole;
Expand Down Expand Up @@ -70,6 +72,12 @@ pub struct Role {
///
/// The `@everyone` role is usually either `-1` or `0`.
pub position: i64,
/// The tags this role has. It can be used to determine if this role is a special role in this guild
/// such as guild subscriber role, or if the role is linked to an [`Integration`] or a bot.
///
/// [`Integration`]: super::Integration
#[serde(default)]
pub tags: RoleTags,
}

#[cfg(feature = "model")]
Expand Down Expand Up @@ -228,3 +236,50 @@ impl FromStrAndCache for Role {
}
}
}

/// The tags of a [`Role`].
#[derive(Clone, Debug, Default, Serialize)]
#[non_exhaustive]
pub struct RoleTags {
/// The Id of the bot the [`Role`] belongs to.
pub bot_id: Option<UserId>,
/// The Id of the integration the [`Role`] belongs to.
pub integration_id: Option<IntegrationId>,
/// Whether this is the guild's premium subscriber role.
#[serde(default)]
pub premium_subscriber: bool,
}

impl<'de> Deserialize<'de> for RoleTags {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;

let bot_id = match map.contains_key("bot_id") {
true => Some(
map.remove("bot_id")
.ok_or_else(|| DeError::custom("expected bot_id"))
.and_then(UserId::deserialize)
.map_err(DeError::custom)?,
),
false => None,
};

let integration_id = match map.contains_key("integration_id") {
true => Some(
map.remove("integration_id")
.ok_or_else(|| DeError::custom("expected integration_id"))
.and_then(IntegrationId::deserialize)
.map_err(DeError::custom)?,
),
false => None,
};

let premium_subscriber = map.contains_key("premium_subscriber");

Ok(Self {
bot_id,
integration_id,
premium_subscriber,
})
}
}
1 change: 1 addition & 0 deletions src/model/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ mod test {
name: "fake role".to_string(),
permissions: Permissions::empty(),
position: 1,
tags: RoleTags::default(),
};
let user = User {
id: UserId(6),
Expand Down
7 changes: 4 additions & 3 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,7 @@ mod test {
name: "ferris-club-member".to_string(),
permissions: Permissions::all(),
position: 0,
tags: RoleTags::default(),
};

let channel = GuildChannel {
Expand Down Expand Up @@ -912,7 +913,7 @@ mod test {
cache.guilds.write().await.insert(guild.id, guild.clone());
cache.channels.write().await.insert(channel.id, channel.clone());

let with_user_metions = "<@!100000000000000000> <@!000000000000000000> <@123> <@!123> \
let with_user_mentions = "<@!100000000000000000> <@!000000000000000000> <@123> <@!123> \
<@!123123123123123123123> <@123> <@123123123123123123> <@!invalid> \
<@invalid> <@日本語 한국어$§)[/__#\\(/&2032$§#> \
<@!i)/==(<<>z/9080)> <@!1231invalid> <@invalid123> \
Expand All @@ -926,7 +927,7 @@ mod test {

// User mentions
let options = ContentSafeOptions::default();
assert_eq!(without_user_mentions, content_safe(&cache, with_user_metions, &options).await);
assert_eq!(without_user_mentions, content_safe(&cache, with_user_mentions, &options).await);

let options = ContentSafeOptions::default();
assert_eq!(
Expand Down Expand Up @@ -959,7 +960,7 @@ mod test {
);

let options = options.clean_user(false);
assert_eq!(with_user_metions, content_safe(&cache, with_user_metions, &options).await);
assert_eq!(with_user_mentions, content_safe(&cache, with_user_mentions, &options).await);

// Channel mentions
let with_channel_mentions = "<#> <#deleted-channel> #deleted-channel <#0> \
Expand Down