Skip to content

Commit 03c6681

Browse files
Add support for gradient roles (#3426)
Splitting out from #3382 to rebase and fix it up. --------- Co-authored-by: jamesbt365 <[email protected]>
1 parent 457f1a7 commit 03c6681

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

src/builder/edit_role.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ pub struct EditRole<'a> {
5454
#[serde(rename = "color")]
5555
colour: Option<Colour>,
5656
#[serde(skip_serializing_if = "Option::is_none")]
57+
#[serde(rename = "colors")]
58+
colours: Option<CreateRoleColours>,
59+
#[serde(skip_serializing_if = "Option::is_none")]
5760
hoist: Option<bool>,
5861
#[serde(skip_serializing_if = "Option::is_none")]
5962
icon: Option<Option<String>>,
@@ -86,6 +89,7 @@ impl<'a> EditRole<'a> {
8689
colour: Some(role.colour),
8790
unicode_emoji: role.unicode_emoji.as_ref().map(|v| Some(v.clone())),
8891
audit_log_reason: None,
92+
colours: Some(role.colours.into()),
8993
// TODO: Do we want to download role.icon?
9094
icon: None,
9195
}
@@ -97,6 +101,12 @@ impl<'a> EditRole<'a> {
97101
self
98102
}
99103

104+
/// Sets the colours of the role. Supports gradient and holographic role colours.
105+
pub fn colours(mut self, colours: impl Into<CreateRoleColours>) -> Self {
106+
self.colours = Some(colours.into());
107+
self
108+
}
109+
100110
/// Whether or not to hoist the role above lower-positioned roles in the user list.
101111
pub fn hoist(mut self, hoist: bool) -> Self {
102112
self.hoist = Some(hoist);
@@ -150,6 +160,55 @@ impl<'a> EditRole<'a> {
150160
}
151161
}
152162

163+
/// The colours of a Discord role, secondary_colour and tertiary_colour may only be set if
164+
/// the [Guild] has the `ENHANCED_ROLE_COLORS` feature.
165+
///
166+
/// Note: 2024-07-05 - tertiary_colour is currently enforced to be set with a specific pair of
167+
/// primary and secondary colours, for current validation see
168+
/// [Discord docs](https://discord.com/developers/docs/topics/permissions#role-object-role-colors-object).
169+
#[derive(Clone, Debug, Default, Serialize)]
170+
#[must_use]
171+
#[allow(clippy::struct_field_names)]
172+
pub struct CreateRoleColours {
173+
primary_color: Colour,
174+
#[serde(skip_serializing_if = "Option::is_none")]
175+
secondary_color: Option<Colour>,
176+
#[serde(skip_serializing_if = "Option::is_none")]
177+
tertiary_color: Option<Colour>,
178+
}
179+
180+
impl CreateRoleColours {
181+
pub fn new(primary_colour: Colour) -> Self {
182+
Self {
183+
primary_color: primary_colour,
184+
secondary_color: None,
185+
tertiary_color: None,
186+
}
187+
}
188+
189+
/// Sets the secondary colour for this role.
190+
pub fn secondary_colour(mut self, secondary_colour: Colour) -> Self {
191+
self.secondary_color = Some(secondary_colour);
192+
self
193+
}
194+
195+
/// Sets the tertiary colour for this role, see struct documentation for limitations.
196+
pub fn tertiary_colour(mut self, tertiary_colour: Colour) -> Self {
197+
self.tertiary_color = Some(tertiary_colour);
198+
self
199+
}
200+
}
201+
202+
impl From<RoleColours> for CreateRoleColours {
203+
fn from(c: RoleColours) -> CreateRoleColours {
204+
CreateRoleColours {
205+
primary_color: c.primary_colour,
206+
secondary_color: c.secondary_colour,
207+
tertiary_color: c.tertiary_colour,
208+
}
209+
}
210+
}
211+
153212
#[cfg(feature = "http")]
154213
#[async_trait::async_trait]
155214
impl Builder for EditRole<'_> {

src/model/colour.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
/// # use serenity::model::id::RoleId;
2020
/// # use serenity::model::id::GuildId;
2121
/// # use serenity::model::permissions;
22+
/// # use serenity::model::guild::RoleColours;
2223
/// #
2324
/// # fn main() {
2425
/// # let role = from_value::<Role>(json!({
2526
/// # "color": Colour::BLURPLE,
27+
/// # "colors": RoleColours::default(),
2628
/// # "hoist": false,
2729
/// # "id": RoleId::new(1),
2830
/// # "guild_id": GuildId::new(2),

src/model/guild/role.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ pub struct Role {
3636
/// The colour of the role.
3737
#[serde(rename = "color")]
3838
pub colour: Colour,
39+
#[serde(rename = "colors")]
40+
pub colours: RoleColours,
3941
/// Indicator of whether the role is pinned above lesser roles.
4042
///
4143
/// In the client, this causes [`Member`]s in the role to be seen above those in roles with a
@@ -76,6 +78,24 @@ pub struct Role {
7678
pub unicode_emoji: Option<String>,
7779
}
7880

81+
/// The colours of a Discord role, secondary_colour and tertiary_colour may only be set if
82+
/// the [Guild] has the `ENHANCED_ROLE_COLORS` feature.
83+
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
84+
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
85+
#[non_exhaustive]
86+
pub struct RoleColours {
87+
/// the primary color for the role
88+
#[serde(rename = "primary_color")]
89+
pub primary_colour: Colour,
90+
/// the secondary color for the role, this will make the role a gradient between the other
91+
/// provided colors
92+
#[serde(rename = "secondary_color")]
93+
pub secondary_colour: Option<Colour>,
94+
/// the tertiary color for the role, this will turn the gradient into a holographic style
95+
#[serde(rename = "tertiary_color")]
96+
pub tertiary_colour: Option<Colour>,
97+
}
98+
7999
#[cfg(feature = "model")]
80100
impl Role {
81101
/// Deletes the role.

0 commit comments

Comments
 (0)