serenity 0.11.5

A Rust library for the Discord API.
Documentation
// Disable this lint to avoid it wanting to change `0xABCDEF` to `0xAB_CDEF`.
#![allow(clippy::unreadable_literal)]

/// A utility struct to help with working with the basic representation of a
/// colour. This is particularly useful when working with a [`Role`]'s colour,
/// as the API works with an integer value instead of an RGB value.
///
/// Instances can be created by using the struct's associated functions. These
/// produce presets equivalent to those found in the official client's colour
/// picker.
///
/// # Examples
///
/// Passing in a role's colour, and then retrieving its green component
/// via [`Self::g`]:
///
/// ```rust
/// # use serde_json::{json, from_value};
/// # use serenity::model::guild::Role;
/// # use serenity::model::id::RoleId;
/// # use serenity::model::id::GuildId;
/// # use serenity::model::permissions;
/// #
/// # fn main() {
/// # let role = from_value::<Role>(json!({
/// #     "color": Colour::BLURPLE,
/// #     "hoist": false,
/// #     "id": RoleId(1),
/// #     "guild_id": GuildId(2),
/// #     "managed": false,
/// #     "mentionable": false,
/// #     "name": "test",
/// #     "permissions": permissions::PRESET_GENERAL,
/// #     "position": 7,
/// # })).unwrap();
/// #
/// use serenity::utils::Colour;
///
/// // assuming a `role` has already been bound
///
/// let green = role.colour.g();
///
/// println!("The green component is: {}", green);
/// # }
/// ```
///
/// Creating an instance with the [`Self::DARK_TEAL`] preset:
///
/// ```rust
/// use serenity::utils::Colour;
///
/// let colour = Colour::DARK_TEAL;
///
/// assert_eq!(colour.tuple(), (17, 128, 106));
/// ```
///
/// Colours can also be directly compared for equivalence:
///
/// ```rust
/// use serenity::utils::Colour;
///
/// let blitz_blue = Colour::BLITZ_BLUE;
/// let fooyoo = Colour::FOOYOO;
/// let fooyoo2 = Colour::FOOYOO;
/// assert!(blitz_blue != fooyoo);
/// assert_eq!(fooyoo, fooyoo2);
/// assert!(blitz_blue > fooyoo);
/// ```
///
/// [`Role`]: crate::model::guild::Role
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub struct Colour(pub u32);

impl Colour {
    /// Generates a new Colour with the given integer value set.
    ///
    /// # Examples
    ///
    /// Create a new Colour, and then ensure that its inner value is equivalent
    /// to a specific RGB value, retrieved via [`Self::tuple`]:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::new(6573123);
    ///
    /// assert_eq!(colour.tuple(), (100, 76, 67));
    /// ```
    #[inline]
    #[must_use]
    pub const fn new(value: u32) -> Colour {
        Colour(value)
    }

    /// Generates a new Colour from an RGB value, creating an inner u32
    /// representation.
    ///
    /// # Examples
    ///
    /// Creating a [`Colour`] via its RGB values will set its inner u32 correctly:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert!(Colour::from_rgb(255, 0, 0).0 == 0xFF0000);
    /// assert!(Colour::from_rgb(217, 23, 211).0 == 0xD917D3);
    /// ```
    ///
    /// And you can then retrieve those same RGB values via its methods:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::from_rgb(217, 45, 215);
    ///
    /// assert_eq!(colour.r(), 217);
    /// assert_eq!(colour.g(), 45);
    /// assert_eq!(colour.b(), 215);
    /// assert_eq!(colour.tuple(), (217, 45, 215));
    /// ```
    // Clippy wants to use `u32::from` instead `as`-casts,
    // but this not doable as `u32::from` is not a const fn.
    #[allow(clippy::cast_lossless)]
    #[must_use]
    pub const fn from_rgb(red: u8, green: u8, blue: u8) -> Colour {
        Colour((red as u32) << 16 | (green as u32) << 8 | blue as u32)
    }

    /// Returns the red RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).r(), 100);
    /// ```
    #[must_use]
    pub const fn r(self) -> u8 {
        ((self.0 >> 16) & 255) as u8
    }

    /// Returns the green RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).g(), 76);
    /// ```
    #[must_use]
    pub const fn g(self) -> u8 {
        ((self.0 >> 8) & 255) as u8
    }

    /// Returns the blue RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).b(), 67);
    /// ```
    #[must_use]
    pub const fn b(self) -> u8 {
        (self.0 & 255) as u8
    }

    /// Returns a tuple of the red, green, and blue components of this Colour.
    ///
    /// This is equivalent to creating a tuple with the return values of
    /// [`Self::r`], [`Self::g`], and [`Self::b`].
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).tuple(), (100, 76, 67));
    /// ```
    #[must_use]
    pub const fn tuple(self) -> (u8, u8, u8) {
        (self.r(), self.g(), self.b())
    }

    /// Returns a hexadecimal string of this Colour.
    ///
    /// This is equivalent to passing the integer value through
    /// [`std::fmt::UpperHex`] with 0 padding and 6 width.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).hex(), "644C43");
    /// ```
    #[must_use]
    pub fn hex(self) -> String {
        format!("{:06X}", self.0)
    }
}

impl From<i32> for Colour {
    /// Constructs a Colour from a i32.
    ///
    /// This is used for functions that accept `Into<Colour>`.
    ///
    /// This is useful when providing hex values.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::from(0xDEA584).tuple(), (222, 165, 132));
    /// ```
    fn from(value: i32) -> Colour {
        Colour(value as u32)
    }
}

impl From<u32> for Colour {
    /// Constructs a Colour from a u32.
    ///
    /// This is used for functions that accept `Into<Colour>`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::from(6573123u32).r(), 100);
    /// ```
    fn from(value: u32) -> Colour {
        Colour(value)
    }
}

impl From<u64> for Colour {
    /// Constructs a Colour from a u32.
    ///
    /// This is used for functions that accept `Into<Colour>`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::from(6573123u64).r(), 100);
    /// ```
    fn from(value: u64) -> Colour {
        Colour(value as u32)
    }
}

impl From<(u8, u8, u8)> for Colour {
    /// Constructs a Colour from RGB.
    fn from((red, green, blue): (u8, u8, u8)) -> Self {
        Colour::from_rgb(red, green, blue)
    }
}

impl Colour {
    /// Creates a new [`Colour`], setting its RGB value to `(111, 198, 226)`.
    pub const BLITZ_BLUE: Colour = Colour(0x6FC6E2);
    /// Creates a new [`Colour`], setting its RGB value to `(52, 152, 219)`.
    pub const BLUE: Colour = Colour(0x3498DB);
    /// Creates a new [`Colour`], setting its RGB value to `(114, 137, 218)`.
    pub const BLURPLE: Colour = Colour(0x7289DA);
    /// Creates a new [`Colour`], setting its RGB value to `(32, 102, 148)`.
    pub const DARK_BLUE: Colour = Colour(0x206694);
    /// Creates a new [`Colour`], setting its RGB value to `(194, 124, 14)`.
    pub const DARK_GOLD: Colour = Colour(0xC27C0E);
    /// Creates a new [`Colour`], setting its RGB value to `(31, 139, 76)`.
    pub const DARK_GREEN: Colour = Colour(0x1F8B4C);
    /// Creates a new [`Colour`], setting its RGB value to `(96, 125, 139)`.
    pub const DARK_GREY: Colour = Colour(0x607D8B);
    /// Creates a new [`Colour`], setting its RGB value to `(173, 20, 87)`.
    pub const DARK_MAGENTA: Colour = Colour(0xAD1457);
    /// Creates a new [`Colour`], setting its RGB value to `(168, 67, 0)`.
    pub const DARK_ORANGE: Colour = Colour(0xA84300);
    /// Creates a new [`Colour`], setting its RGB value to `(113, 54, 138)`.
    pub const DARK_PURPLE: Colour = Colour(0x71368A);
    /// Creates a new [`Colour`], setting its RGB value to `(153, 45, 34)`.
    pub const DARK_RED: Colour = Colour(0x992D22);
    /// Creates a new [`Colour`], setting its RGB value to `(17, 128, 106)`.
    pub const DARK_TEAL: Colour = Colour(0x11806A);
    /// Creates a new [`Colour`], setting its RGB value to `(84, 110, 122)`.
    pub const DARKER_GREY: Colour = Colour(0x546E7A);
    /// Creates a new [`Colour`], setting its RGB value to `(250, 177, 237)`.
    pub const FABLED_PINK: Colour = Colour(0xFAB1ED);
    /// Creates a new [`Colour`], setting its RGB value to `(136, 130, 196)`.
    pub const FADED_PURPLE: Colour = Colour(0x8882C4);
    /// Creates a new [`Colour`], setting its RGB value to `(17, 202, 128)`.
    pub const FOOYOO: Colour = Colour(0x11CA80);
    /// Creates a new [`Colour`], setting its RGB value to `(241, 196, 15)`.
    pub const GOLD: Colour = Colour(0xF1C40F);
    /// Creates a new [`Colour`], setting its RGB value to `(186, 218, 85)`.
    pub const KERBAL: Colour = Colour(0xBADA55);
    /// Creates a new [`Colour`], setting its RGB value to `(151, 156, 159)`.
    pub const LIGHT_GREY: Colour = Colour(0x979C9F);
    /// Creates a new [`Colour`], setting its RGB value to `(149, 165, 166)`.
    pub const LIGHTER_GREY: Colour = Colour(0x95A5A6);
    /// Creates a new [`Colour`], setting its RGB value to `(233, 30, 99)`.
    pub const MAGENTA: Colour = Colour(0xE91E63);
    /// Creates a new [`Colour`], setting its RGB value to `(230, 131, 151)`.
    pub const MEIBE_PINK: Colour = Colour(0xE68397);
    /// Creates a new [`Colour`], setting its RGB value to `(230, 126, 34)`.
    pub const ORANGE: Colour = Colour(0xE67E22);
    /// Creates a new [`Colour`], setting its RGB value to `(155, 89, 182)`.
    pub const PURPLE: Colour = Colour(0x9B59B6);
    /// Creates a new [`Colour`], setting its RGB value to `(231, 76, 60)`.
    pub const RED: Colour = Colour(0xE74C3C);
    /// Creates a new [`Colour`], setting its RGB value to `(117, 150, 255)`.
    pub const ROHRKATZE_BLUE: Colour = Colour(0x7596FF);
    /// Creates a new [`Colour`], setting its RGB value to `(246, 219, 216)`.
    pub const ROSEWATER: Colour = Colour(0xF6DBD8);
    /// Creates a new [`Colour`], setting its RGB value to `(26, 188, 156)`.
    pub const TEAL: Colour = Colour(0x1ABC9C);
}

impl Default for Colour {
    /// Creates a default value for a [`Colour`], setting the inner value to `0`.
    fn default() -> Colour {
        Colour(0)
    }
}

/// Colour constants used by Discord for their branding, role colour palette, etc.
pub mod colours {
    pub mod branding {
        use crate::utils::Colour;

        /// Creates a new [`Colour`], setting its value to `rgb(88, 101, 242)`.
        pub const BLURPLE: Colour = Colour(0x5865F2);
        /// Creates a new [`Colour`], setting its value to `rgb(87, 242, 135)`.
        pub const GREEN: Colour = Colour(0x57F287);
        /// Creates a new [`Colour`], setting its value to `rgb(254, 231, 92)`.
        pub const YELLOW: Colour = Colour(0xFEE75C);
        /// Creates a new [`Colour`], setting its value to `rgb(235, 69, 158)`.
        pub const FUCHSIA: Colour = Colour(0xEB459E);
        /// Creates a new [`Colour`], setting its value to `rgb(237, 66, 69)`.
        pub const RED: Colour = Colour(0xED4245);
        /// Creates a new [`Colour`], setting its value to `rgb(255, 255, 255)`.
        pub const WHITE: Colour = Colour(0xFFFFFF);
        /// Creates a new [`Colour`], setting its value to `rgb(35, 39, 42)`.
        pub const BLACK: Colour = Colour(0x23272A);
    }
    pub mod css {
        use crate::utils::Colour;

        /// Creates a new [`Colour`], setting its value to `hsl(139, 47.3%, 43.9%)`.
        pub const POSITIVE: Colour = Colour(0x3BA55D);
        /// Creates a new [`Colour`], setting its value to `hsl(38, 95.7%, 54.1%)`.
        pub const WARNING: Colour = Colour(0xFAA81A);
        /// Creates a new [`Colour`], setting its value to `hsl(359, 82.6%, 59.4%)`.
        pub const DANGER: Colour = Colour(0xED4245);
    }
    pub mod roles {
        use crate::utils::Colour;

        /// Creates a new [`Colour`], setting its value to `rgb(153, 170, 181)`.
        pub const DEFAULT: Colour = Colour(0x99AAB5);
        /// Creates a new [`Colour`], setting its value to `rgb(26, 188, 156)`.
        pub const TEAL: Colour = Colour(0x1ABC9C);
        /// Creates a new [`Colour`], setting its value to `rgb(17, 128, 106)`.
        pub const DARK_TEAL: Colour = Colour(0x11806A);
        /// Creates a new [`Colour`], setting its value to `rgb(46, 204, 113)`.
        pub const GREEN: Colour = Colour(0x2ECC71);
        /// Creates a new [`Colour`], setting its value to `rgb(31, 139, 76)`.
        pub const DARK_GREEN: Colour = Colour(0x1F8B4C);
        /// Creates a new [`Colour`], setting its value to `rgb(52, 152, 219)`.
        pub const BLUE: Colour = Colour(0x3498DB);
        /// Creates a new [`Colour`], setting its value to `rgb(32, 102, 148)`.
        pub const DARK_BLUE: Colour = Colour(0x206694);
        /// Creates a new [`Colour`], setting its value to `rgb(155, 89, 182)`.
        pub const PURPLE: Colour = Colour(0x9B59B6);
        /// Creates a new [`Colour`], setting its value to `rgb(113, 54, 138)`.
        pub const DARK_PURPLE: Colour = Colour(0x71368A);
        /// Creates a new [`Colour`], setting its value to `rgb(233, 30, 99)`.
        pub const MAGENTA: Colour = Colour(0xE91E63);
        /// Creates a new [`Colour`], setting its value to `rgb(173, 20, 87)`.
        pub const DARK_MAGENTA: Colour = Colour(0xAD1457);
        /// Creates a new [`Colour`], setting its value to `rgb(241, 196, 15)`.
        pub const GOLD: Colour = Colour(0xF1C40F);
        /// Creates a new [`Colour`], setting its value to `rgb(194, 124, 14)`.
        pub const DARK_GOLD: Colour = Colour(0xC27C0E);
        /// Creates a new [`Colour`], setting its value to `rgb(230, 126, 34)`.
        pub const ORANGE: Colour = Colour(0xE67E22);
        /// Creates a new [`Colour`], setting its value to `rgb(168, 67, 0)`.
        pub const DARK_ORANGE: Colour = Colour(0xA84300);
        /// Creates a new [`Colour`], setting its value to `rgb(231, 76, 60)`.
        pub const RED: Colour = Colour(0xE74C3C);
        /// Creates a new [`Colour`], setting its value to `rgb(153, 45, 34)`.
        pub const DARK_RED: Colour = Colour(0x992D22);
        /// Creates a new [`Colour`], setting its value to `rgb(149, 165, 166)`.
        pub const LIGHTER_GREY: Colour = Colour(0x95A5A6);
        /// Creates a new [`Colour`], setting its value to `rgb(151, 156, 159)`.
        pub const LIGHT_GREY: Colour = Colour(0x979C9F);
        /// Creates a new [`Colour`], setting its value to `rgb(96, 125, 139)`.
        pub const DARK_GREY: Colour = Colour(0x607D8B);
        /// Creates a new [`Colour`], setting its value to `rgb(84, 110, 122)`.
        pub const DARKER_GREY: Colour = Colour(0x546E7A);
    }
}

#[cfg(test)]
mod test {
    use std::u32;

    use super::Colour;

    #[test]
    fn new() {
        assert_eq!(Colour::new(1).0, 1);
        assert_eq!(Colour::new(u32::MIN).0, u32::MIN);
        assert_eq!(Colour::new(u32::MAX).0, u32::MAX);
    }

    #[test]
    fn from_rgb() {
        assert_eq!(Colour::from_rgb(255, 0, 0).0, 0xFF0000);
        assert_eq!(Colour::from_rgb(0, 255, 0).0, 0x00FF00);
        assert_eq!(Colour::from_rgb(0, 0, 255).0, 0x0000FF);
    }

    #[test]
    fn r() {
        assert_eq!(Colour::new(0x336123).r(), 0x33);
    }

    #[test]
    fn g() {
        assert_eq!(Colour::new(0x336123).g(), 0x61);
    }

    #[test]
    fn b() {
        assert_eq!(Colour::new(0x336123).b(), 0x23);
    }

    #[test]
    fn tuple() {
        assert_eq!(Colour::new(0x336123).tuple(), (0x33, 0x61, 0x23));
    }

    #[test]
    fn default() {
        assert_eq!(Colour::default().0, 0);
    }

    #[test]
    fn from() {
        assert_eq!(Colour::from(7i32).0, 7);
        assert_eq!(Colour::from(7u32).0, 7);
        assert_eq!(Colour::from(7u64).0, 7);
    }
}