<commit_before>macro_rules! colour {
    ($(#[$attr:meta] $name:ident, $val:expr;)*) => {
        impl Colour {
            $(
                #[$attr]
                pub fn $name() -> Colour {
                    Colour::new($val)
                }
            )*
        }
    }
}

/// 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 [`g`]:
///
/// ```rust
/// # use serenity::model::{Role, RoleId, permissions};
/// use serenity::utils::Colour;
/// #
/// # let role = Role {
/// #     colour: Colour::blurple(),
/// #     hoist: false,
/// #     id: RoleId(1),
/// #     managed: false,
/// #     mentionable: false,
/// #     name: "test".to_owned(),
/// #     permissions: permissions::PRESET_GENERAL,
/// #     position: 7,
/// # };
///
/// // assuming a `role` has already been bound
///
/// let green = role.colour.g();
///
/// println!("The green component is: {}", green);
/// ```
///
/// Creating an instance with the [`dark_teal`] presets:
///
/// ```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`]: ../model/struct.Role.html
/// [`dark_teal`]: #method.dark_teal
/// [`g`]: #method.g
#[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 [`tuple`]:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::new(6573123);
    ///
    /// assert_eq!(colour.tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`tuple`]: #method.tuple
    #[inline]
    pub 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));
    /// ```
    pub fn from_rgb(r: u8, g: u8, b: u8) -> Colour {
        let mut uint = r as u32;
        uint = (uint << 8) | (g as u32);
        uint = (uint << 8) | (b as u32);

        Colour(uint)
    }

    /// Returns the red RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).r(), 100);
    /// ```
    pub 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);
    /// ```
    pub 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);
    pub 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
    /// [`r`], [`g`], and [`b`].
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`r`]: #method.r
    /// [`g`]: #method.g
    /// [`b`]: #method.b
    pub fn tuple(&self) -> (u8, u8, u8) { (self.r(), self.g(), self.b()) }
}

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) }
}

colour! {
    /// Creates a new `Colour`, setting its RGB value to `(111, 198, 226)`.
    blitz_blue, 0x6FC6E2;
    /// Creates a new `Colour`, setting its RGB value to `(52, 152, 219)`.
    blue, 0x3498DB;
    /// Creates a new `Colour`, setting its RGB value to `(114, 137, 218)`.
    blurple, 0x7289DA;
    /// Creates a new `Colour`, setting its RGB value to `(32, 102, 148)`.
    dark_blue, 0x206694;
    /// Creates a new `Colour`, setting its RGB value to `(194, 124, 14)`.
    dark_gold, 0xC27C0E;
    /// Creates a new `Colour`, setting its RGB value to `(31, 139, 76)`.
    dark_green, 0x1F8B4C;
    /// Creates a new `Colour`, setting its RGB value to `(96, 125, 139)`.
    dark_grey, 0x607D8B;
    /// Creates a new `Colour`, setting its RGB value to `(173, 20, 87)`.
    dark_magenta, 0xAD1457;
    /// Creates a new `Colour`, setting its RGB value to `(168, 67, 0)`.
    dark_orange, 0xA84300;
    /// Creates a new `Colour`, setting its RGB value to `(113, 54, 138)`.
    dark_purple, 0x71368A;
    /// Creates a new `Colour`, setting its RGB value to `(153, 45, 34)`.
    dark_red, 0x992D22;
    /// Creates a new `Colour`, setting its RGB value to `(17, 128, 106)`.
    dark_teal, 0x11806A;
    /// Creates a new `Colour`, setting its RGB value to `(84, 110, 122)`.
    darker_grey, 0x546E7A;
    /// Creates a new `Colour`, setting its RGB value to `(250, 177, 237)`.
    fabled_pink, 0xFAB1ED;
    /// Creates a new `Colour`, setting its RGB value to `(136, 130, 196)`.`
    faded_purple, 0x8882C4;
    /// Creates a new `Colour`, setting its RGB value to `(17, 202, 128)`.
    fooyoo, 0x11CA80;
    /// Creates a new `Colour`, setting its RGB value to `(241, 196, 15)`.
    gold, 0xF1C40F;
    /// Creates a new `Colour`, setting its RGB value to `(186, 218, 85)`.
    kerbal, 0xBADA55;
    /// Creates a new `Colour`, setting its RGB value to `(151, 156, 159)`.
    light_grey, 0x979C9F;
    /// Creates a new `Colour`, setting its RGB value to `(149, 165, 166)`.
    lighter_grey, 0x95A5A6;
    /// Creates a new `Colour`, setting its RGB value to `(233, 30, 99)`.
    magenta, 0xE91E63;
    /// Creates a new `Colour`, setting its RGB value to `(230, 131, 151)`.
    meibe_pink, 0xE68397;
    /// Creates a new `Colour`, setting its RGB value to `(230, 126, 34)`.
    orange, 0xE67E22;
    /// Creates a new `Colour`, setting its RGB value to `(155, 89, 182)`.
    purple, 0x9B59B6;
    /// Creates a new `Colour`, setting its RGB value to `(231, 76, 60)`.
    red, 0xE74C3C;
    /// Creates a new `Colour`, setting its RGB value to `(117, 150, 255)`.
    rohrkatze_blue, 0x7596FF;
    /// Creates a new `Colour`, setting its RGB value to `(246, 219, 216)`.
    rosewater, 0xF6DBD8;
    /// Creates a new `Colour`, setting its RGB value to `(26, 188, 156)`.
    teal, 0x1ABC9C;
}

impl Default for Colour {
    /// Creates a default value for a `Colour`, setting the inner value to `0`.
    fn default() -> Colour { Colour(0) }
}
<commit_msg>Make colour implement `From<(u8, u8, u8)>`<commit_after>macro_rules! colour {
    ($(#[$attr:meta] $name:ident, $val:expr;)*) => {
        impl Colour {
            $(
                #[$attr]
                pub fn $name() -> Colour {
                    Colour::new($val)
                }
            )*
        }
    }
}

/// 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 [`g`]:
///
/// ```rust
/// # use serenity::model::{Role, RoleId, permissions};
/// use serenity::utils::Colour;
/// #
/// # let role = Role {
/// #     colour: Colour::blurple(),
/// #     hoist: false,
/// #     id: RoleId(1),
/// #     managed: false,
/// #     mentionable: false,
/// #     name: "test".to_owned(),
/// #     permissions: permissions::PRESET_GENERAL,
/// #     position: 7,
/// # };
///
/// // assuming a `role` has already been bound
///
/// let green = role.colour.g();
///
/// println!("The green component is: {}", green);
/// ```
///
/// Creating an instance with the [`dark_teal`] presets:
///
/// ```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`]: ../model/struct.Role.html
/// [`dark_teal`]: #method.dark_teal
/// [`g`]: #method.g
#[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 [`tuple`]:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::new(6573123);
    ///
    /// assert_eq!(colour.tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`tuple`]: #method.tuple
    #[inline]
    pub 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));
    /// ```
    pub fn from_rgb(r: u8, g: u8, b: u8) -> Colour {
        let mut uint = r as u32;
        uint = (uint << 8) | (g as u32);
        uint = (uint << 8) | (b as u32);

        Colour(uint)
    }

    /// Returns the red RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).r(), 100);
    /// ```
    pub 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);
    /// ```
    pub 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);
    pub 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
    /// [`r`], [`g`], and [`b`].
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`r`]: #method.r
    /// [`g`]: #method.g
    /// [`b`]: #method.b
    pub fn tuple(&self) -> (u8, u8, u8) { (self.r(), self.g(), self.b()) }
}

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((r, g,b): (u8, u8, u8)) -> Self { Colour::from_rgb(r, g, b) }
}

colour! {
    /// Creates a new `Colour`, setting its RGB value to `(111, 198, 226)`.
    blitz_blue, 0x6FC6E2;
    /// Creates a new `Colour`, setting its RGB value to `(52, 152, 219)`.
    blue, 0x3498DB;
    /// Creates a new `Colour`, setting its RGB value to `(114, 137, 218)`.
    blurple, 0x7289DA;
    /// Creates a new `Colour`, setting its RGB value to `(32, 102, 148)`.
    dark_blue, 0x206694;
    /// Creates a new `Colour`, setting its RGB value to `(194, 124, 14)`.
    dark_gold, 0xC27C0E;
    /// Creates a new `Colour`, setting its RGB value to `(31, 139, 76)`.
    dark_green, 0x1F8B4C;
    /// Creates a new `Colour`, setting its RGB value to `(96, 125, 139)`.
    dark_grey, 0x607D8B;
    /// Creates a new `Colour`, setting its RGB value to `(173, 20, 87)`.
    dark_magenta, 0xAD1457;
    /// Creates a new `Colour`, setting its RGB value to `(168, 67, 0)`.
    dark_orange, 0xA84300;
    /// Creates a new `Colour`, setting its RGB value to `(113, 54, 138)`.
    dark_purple, 0x71368A;
    /// Creates a new `Colour`, setting its RGB value to `(153, 45, 34)`.
    dark_red, 0x992D22;
    /// Creates a new `Colour`, setting its RGB value to `(17, 128, 106)`.
    dark_teal, 0x11806A;
    /// Creates a new `Colour`, setting its RGB value to `(84, 110, 122)`.
    darker_grey, 0x546E7A;
    /// Creates a new `Colour`, setting its RGB value to `(250, 177, 237)`.
    fabled_pink, 0xFAB1ED;
    /// Creates a new `Colour`, setting its RGB value to `(136, 130, 196)`.`
    faded_purple, 0x8882C4;
    /// Creates a new `Colour`, setting its RGB value to `(17, 202, 128)`.
    fooyoo, 0x11CA80;
    /// Creates a new `Colour`, setting its RGB value to `(241, 196, 15)`.
    gold, 0xF1C40F;
    /// Creates a new `Colour`, setting its RGB value to `(186, 218, 85)`.
    kerbal, 0xBADA55;
    /// Creates a new `Colour`, setting its RGB value to `(151, 156, 159)`.
    light_grey, 0x979C9F;
    /// Creates a new `Colour`, setting its RGB value to `(149, 165, 166)`.
    lighter_grey, 0x95A5A6;
    /// Creates a new `Colour`, setting its RGB value to `(233, 30, 99)`.
    magenta, 0xE91E63;
    /// Creates a new `Colour`, setting its RGB value to `(230, 131, 151)`.
    meibe_pink, 0xE68397;
    /// Creates a new `Colour`, setting its RGB value to `(230, 126, 34)`.
    orange, 0xE67E22;
    /// Creates a new `Colour`, setting its RGB value to `(155, 89, 182)`.
    purple, 0x9B59B6;
    /// Creates a new `Colour`, setting its RGB value to `(231, 76, 60)`.
    red, 0xE74C3C;
    /// Creates a new `Colour`, setting its RGB value to `(117, 150, 255)`.
    rohrkatze_blue, 0x7596FF;
    /// Creates a new `Colour`, setting its RGB value to `(246, 219, 216)`.
    rosewater, 0xF6DBD8;
    /// Creates a new `Colour`, setting its RGB value to `(26, 188, 156)`.
    teal, 0x1ABC9C;
}

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


<commit_before>// Disable this lint to avoid it wanting to change `0xABCDEF` to `0xAB_CDEF`.
#![allow(unreadable_literal)]

macro_rules! colour {
    ($(#[$attr:meta] $constname:ident, $name:ident, $val:expr;)*) => {
        impl Colour {
            $(
                #[$attr]
                pub const $constname: Colour = Colour($val);
            )*

            $(
                #[$attr]
                #[deprecated(note = "Use the constant instead", since = "0.5.5")]
                pub fn $name() -> Colour {
                    Colour::new($val)
                }
            )*
        }
    }
}

/// 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 [`g`]:
///
/// ```rust
/// # use serenity::model::guild::Role;
/// # use serenity::model::id::RoleId;
/// # use serenity::model::permissions;
/// #
/// # let role = Role {
/// #     colour: Colour::BLURPLE,
/// #     hoist: false,
/// #     id: RoleId(1),
/// #     managed: false,
/// #     mentionable: false,
/// #     name: "test".to_string(),
/// #     permissions: permissions::PRESET_GENERAL,
/// #     position: 7,
/// # };
/// #
/// 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 [`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`]: ../model/guild/struct.Role.html
/// [`DARK_TEAL`]: #associatedconstant.DARK_TEAL
/// [`g`]: #method.g
#[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 [`tuple`]:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::new(6573123);
    ///
    /// assert_eq!(colour.tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`tuple`]: #method.tuple
    #[inline]
    pub 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));
    /// ```
    pub fn from_rgb(red: u8, green: u8, blue: u8) -> Colour {
        let mut uint = u32::from(red);
        uint = (uint << 8) | (u32::from(green));
        uint = (uint << 8) | (u32::from(blue));

        Colour(uint)
    }

    /// Returns the red RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).r(), 100);
    /// ```
    pub 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);
    /// ```
    pub 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);
    pub 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
    /// [`r`], [`g`], and [`b`].
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`r`]: #method.r
    /// [`g`]: #method.g
    /// [`b`]: #method.b
    pub fn tuple(&self) -> (u8, u8, u8) { (self.r(), self.g(), self.b()) }
}

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)
    }
}

colour! {
    /// Creates a new `Colour`, setting its RGB value to `(111, 198, 226)`.
    BLITZ_BLUE, blitz_blue, 0x6FC6E2;
    /// Creates a new `Colour`, setting its RGB value to `(52, 152, 219)`.
    BLUE, blue, 0x3498DB;
    /// Creates a new `Colour`, setting its RGB value to `(114, 137, 218)`.
    BLURPLE, blurple, 0x7289DA;
    /// Creates a new `Colour`, setting its RGB value to `(32, 102, 148)`.
    DARK_BLUE, dark_blue, 0x206694;
    /// Creates a new `Colour`, setting its RGB value to `(194, 124, 14)`.
    DARK_GOLD, dark_gold, 0xC27C0E;
    /// Creates a new `Colour`, setting its RGB value to `(31, 139, 76)`.
    DARK_GREEN, dark_green, 0x1F8B4C;
    /// Creates a new `Colour`, setting its RGB value to `(96, 125, 139)`.
    DARK_GREY, dark_grey, 0x607D8B;
    /// Creates a new `Colour`, setting its RGB value to `(173, 20, 87)`.
    DARK_MAGENTA, dark_magenta, 0xAD1457;
    /// Creates a new `Colour`, setting its RGB value to `(168, 67, 0)`.
    DARK_ORANGE, dark_orange, 0xA84300;
    /// Creates a new `Colour`, setting its RGB value to `(113, 54, 138)`.
    DARK_PURPLE, dark_purple, 0x71368A;
    /// Creates a new `Colour`, setting its RGB value to `(153, 45, 34)`.
    DARK_RED, dark_red, 0x992D22;
    /// Creates a new `Colour`, setting its RGB value to `(17, 128, 106)`.
    DARK_TEAL, dark_teal, 0x11806A;
    /// Creates a new `Colour`, setting its RGB value to `(84, 110, 122)`.
    DARKER_GREY, darker_grey, 0x546E7A;
    /// Creates a new `Colour`, setting its RGB value to `(250, 177, 237)`.
    FABLED_PINK, fabled_pink, 0xFAB1ED;
    /// Creates a new `Colour`, setting its RGB value to `(136, 130, 196)`.`
    FADED_PURPLE, faded_purple, 0x8882C4;
    /// Creates a new `Colour`, setting its RGB value to `(17, 202, 128)`.
    FOOYOO, fooyoo, 0x11CA80;
    /// Creates a new `Colour`, setting its RGB value to `(241, 196, 15)`.
    GOLD, gold, 0xF1C40F;
    /// Creates a new `Colour`, setting its RGB value to `(186, 218, 85)`.
    KERBAL, kerbal, 0xBADA55;
    /// Creates a new `Colour`, setting its RGB value to `(151, 156, 159)`.
    LIGHT_GREY, light_grey, 0x979C9F;
    /// Creates a new `Colour`, setting its RGB value to `(149, 165, 166)`.
    LIGHTER_GREY, lighter_grey, 0x95A5A6;
    /// Creates a new `Colour`, setting its RGB value to `(233, 30, 99)`.
    MAGENTA, magenta, 0xE91E63;
    /// Creates a new `Colour`, setting its RGB value to `(230, 131, 151)`.
    MEIBE_PINK, meibe_pink, 0xE68397;
    /// Creates a new `Colour`, setting its RGB value to `(230, 126, 34)`.
    ORANGE, orange, 0xE67E22;
    /// Creates a new `Colour`, setting its RGB value to `(155, 89, 182)`.
    PURPLE, purple, 0x9B59B6;
    /// Creates a new `Colour`, setting its RGB value to `(231, 76, 60)`.
    RED, red, 0xE74C3C;
    /// Creates a new `Colour`, setting its RGB value to `(117, 150, 255)`.
    ROHRKATZE_BLUE, rohrkatze_blue, 0x7596FF;
    /// Creates a new `Colour`, setting its RGB value to `(246, 219, 216)`.
    ROSEWATER, rosewater, 0xF6DBD8;
    /// Creates a new `Colour`, setting its RGB value to `(26, 188, 156)`.
    TEAL, teal, 0x1ABC9C;
}

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

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

    #[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);
    }
}
<commit_msg>Add Colour::hex<commit_after>// Disable this lint to avoid it wanting to change `0xABCDEF` to `0xAB_CDEF`.
#![allow(unreadable_literal)]

macro_rules! colour {
    ($(#[$attr:meta] $constname:ident, $name:ident, $val:expr;)*) => {
        impl Colour {
            $(
                #[$attr]
                pub const $constname: Colour = Colour($val);
            )*

            $(
                #[$attr]
                #[deprecated(note = "Use the constant instead", since = "0.5.5")]
                pub fn $name() -> Colour {
                    Colour::new($val)
                }
            )*
        }
    }
}

/// 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 [`g`]:
///
/// ```rust
/// # use serenity::model::guild::Role;
/// # use serenity::model::id::RoleId;
/// # use serenity::model::permissions;
/// #
/// # let role = Role {
/// #     colour: Colour::BLURPLE,
/// #     hoist: false,
/// #     id: RoleId(1),
/// #     managed: false,
/// #     mentionable: false,
/// #     name: "test".to_string(),
/// #     permissions: permissions::PRESET_GENERAL,
/// #     position: 7,
/// # };
/// #
/// 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 [`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`]: ../model/guild/struct.Role.html
/// [`DARK_TEAL`]: #associatedconstant.DARK_TEAL
/// [`g`]: #method.g
#[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 [`tuple`]:
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// let colour = Colour::new(6573123);
    ///
    /// assert_eq!(colour.tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`tuple`]: #method.tuple
    #[inline]
    pub 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));
    /// ```
    pub fn from_rgb(red: u8, green: u8, blue: u8) -> Colour {
        let mut uint = u32::from(red);
        uint = (uint << 8) | (u32::from(green));
        uint = (uint << 8) | (u32::from(blue));

        Colour(uint)
    }

    /// Returns the red RGB component of this Colour.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).r(), 100);
    /// ```
    pub 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);
    /// ```
    pub 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);
    pub 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
    /// [`r`], [`g`], and [`b`].
    ///
    /// # Examples
    ///
    /// ```rust
    /// use serenity::utils::Colour;
    ///
    /// assert_eq!(Colour::new(6573123).tuple(), (100, 76, 67));
    /// ```
    ///
    /// [`r`]: #method.r
    /// [`g`]: #method.g
    /// [`b`]: #method.b
    pub 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");
    /// ```
    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)
    }
}

colour! {
    /// Creates a new `Colour`, setting its RGB value to `(111, 198, 226)`.
    BLITZ_BLUE, blitz_blue, 0x6FC6E2;
    /// Creates a new `Colour`, setting its RGB value to `(52, 152, 219)`.
    BLUE, blue, 0x3498DB;
    /// Creates a new `Colour`, setting its RGB value to `(114, 137, 218)`.
    BLURPLE, blurple, 0x7289DA;
    /// Creates a new `Colour`, setting its RGB value to `(32, 102, 148)`.
    DARK_BLUE, dark_blue, 0x206694;
    /// Creates a new `Colour`, setting its RGB value to `(194, 124, 14)`.
    DARK_GOLD, dark_gold, 0xC27C0E;
    /// Creates a new `Colour`, setting its RGB value to `(31, 139, 76)`.
    DARK_GREEN, dark_green, 0x1F8B4C;
    /// Creates a new `Colour`, setting its RGB value to `(96, 125, 139)`.
    DARK_GREY, dark_grey, 0x607D8B;
    /// Creates a new `Colour`, setting its RGB value to `(173, 20, 87)`.
    DARK_MAGENTA, dark_magenta, 0xAD1457;
    /// Creates a new `Colour`, setting its RGB value to `(168, 67, 0)`.
    DARK_ORANGE, dark_orange, 0xA84300;
    /// Creates a new `Colour`, setting its RGB value to `(113, 54, 138)`.
    DARK_PURPLE, dark_purple, 0x71368A;
    /// Creates a new `Colour`, setting its RGB value to `(153, 45, 34)`.
    DARK_RED, dark_red, 0x992D22;
    /// Creates a new `Colour`, setting its RGB value to `(17, 128, 106)`.
    DARK_TEAL, dark_teal, 0x11806A;
    /// Creates a new `Colour`, setting its RGB value to `(84, 110, 122)`.
    DARKER_GREY, darker_grey, 0x546E7A;
    /// Creates a new `Colour`, setting its RGB value to `(250, 177, 237)`.
    FABLED_PINK, fabled_pink, 0xFAB1ED;
    /// Creates a new `Colour`, setting its RGB value to `(136, 130, 196)`.`
    FADED_PURPLE, faded_purple, 0x8882C4;
    /// Creates a new `Colour`, setting its RGB value to `(17, 202, 128)`.
    FOOYOO, fooyoo, 0x11CA80;
    /// Creates a new `Colour`, setting its RGB value to `(241, 196, 15)`.
    GOLD, gold, 0xF1C40F;
    /// Creates a new `Colour`, setting its RGB value to `(186, 218, 85)`.
    KERBAL, kerbal, 0xBADA55;
    /// Creates a new `Colour`, setting its RGB value to `(151, 156, 159)`.
    LIGHT_GREY, light_grey, 0x979C9F;
    /// Creates a new `Colour`, setting its RGB value to `(149, 165, 166)`.
    LIGHTER_GREY, lighter_grey, 0x95A5A6;
    /// Creates a new `Colour`, setting its RGB value to `(233, 30, 99)`.
    MAGENTA, magenta, 0xE91E63;
    /// Creates a new `Colour`, setting its RGB value to `(230, 131, 151)`.
    MEIBE_PINK, meibe_pink, 0xE68397;
    /// Creates a new `Colour`, setting its RGB value to `(230, 126, 34)`.
    ORANGE, orange, 0xE67E22;
    /// Creates a new `Colour`, setting its RGB value to `(155, 89, 182)`.
    PURPLE, purple, 0x9B59B6;
    /// Creates a new `Colour`, setting its RGB value to `(231, 76, 60)`.
    RED, red, 0xE74C3C;
    /// Creates a new `Colour`, setting its RGB value to `(117, 150, 255)`.
    ROHRKATZE_BLUE, rohrkatze_blue, 0x7596FF;
    /// Creates a new `Colour`, setting its RGB value to `(246, 219, 216)`.
    ROSEWATER, rosewater, 0xF6DBD8;
    /// Creates a new `Colour`, setting its RGB value to `(26, 188, 156)`.
    TEAL, teal, 0x1ABC9C;
}

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

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

    #[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);
    }
}
<|endoftext|>


<commit_before>use std::Option;

struct Tree<T> {
    root: Option<~Node<T>>
}
pub struct Node<T> {
    left_child: Option<~Node<T>>,
    right_child: Option<~Node<T>>,
    key: T
}

impl<T:Ord> Node<T> {
    pub fn new (nodeKey: T) -> Node<T> {
        Node {
            left_child: None,
            right_child: None,
            key: nodeKey
        }
    }

    pub fn add_child_node(&mut self, new_node: ~Node<T>) {
        if new_node.key > self.key {
            self.add_right_child(new_node);
        }
        else {
            self.add_left_child(new_node);
        }
    }

    fn add_right_child(&mut self, new_node: ~Node<T>) {
        match self.right_child {
            None => {
                self.right_child = Some(new_node);
            },
            Some(ref mut right_child) => {
                right_child.add_child_node(new_node);
            }
        }
    }

    fn add_left_child(&mut self, new_node: ~Node<T>) {
        match self.left_child {
            None => {
                self.left_child = Some(new_node);
            },
            Some(ref mut left_child) => {
                left_child.add_child_node(new_node);
            }
        }
    }

    pub fn has_children(node: &Node<T>) -> bool {
        match node.left_child {
            Some(_) => true,
            _ => {
                match node.right_child {
                    Some(_) => true,
                    _ => false
                }
            }
        }
    }

    pub fn visit_in_order(&self, visitor: &fn(&Node<T>)) {
        match self.left_child {
            Some (ref n) => {
                n.visit_in_order(visitor);
            },
            _ => {}
        }

        visitor(self);

        match self.right_child {
            Some (ref n) => {
                n.visit_in_order(visitor);
            },
            _ => {}
        }
    }
}

pub impl<T:Ord> Tree<T> {
    pub fn new () -> Tree<T> {
        Tree {
            root: None
        }
    }

    fn insert_value (&mut self, value: T) {
        let new_node = ~Node::new(value);
        self.insert_node(new_node);
    }

    fn insert_node (&mut self, new_node: ~Node<T>) {
        match self.root {
            None => {
                self.root = Some(new_node);
            },
            Some(ref mut n) => {
                n.add_child_node(new_node);
            }
        }
    }

    fn visit_in_order (&self, visitor: &fn(&Node<T>)) {
        match self.root {
            Some(ref n) => {
                n.visit_in_order(visitor);
            },
            _ => {
            }
        }
    }
}

fn main () {
    let mut myTree: Tree<int> = Tree::new();

    myTree.insert_value(3);
    myTree.insert_value(2);
    myTree.insert_value(4);
    myTree.insert_value(0);

    myTree.visit_in_order(|n| {
                          std::io::println(fmt!("%d", n.key));
                          });
}
<commit_msg>Add a pointer to the node parent.<commit_after>use std::Option;
use std::ptr;

struct Tree<T> {
    root: Option<~Node<T>>
}
pub struct Node<T> {
    left_child: Option<~Node<T>>,
    right_child: Option<~Node<T>>,
    parent: Option<*const Node<T>>,
    key: T
}

impl<T:Ord> Node<T> {
    pub fn new (nodeKey: T) -> Node<T> {
        Node {
            left_child: None,
            right_child: None,
            parent: None,
            key: nodeKey
        }
    }

    pub fn add_child_node(&mut self, new_node: ~Node<T>) {
        if new_node.key > self.key {
            self.add_right_child(new_node);
        }
        else {
            self.add_left_child(new_node);
        }
    }

    fn add_right_child(&mut self, mut new_node: ~Node<T>) {
        match self.right_child {
            None => {
                new_node.parent = Some(ptr::to_const_unsafe_ptr(self));
                self.right_child = Some(new_node);
            },
            Some(ref mut right_child) => {
                right_child.add_child_node(new_node);
            }
        }
    }

    fn add_left_child(&mut self, mut new_node: ~Node<T>) {
        match self.left_child {
            None => {
                new_node.parent = Some(ptr::to_const_unsafe_ptr(self));
                self.left_child = Some(new_node);
            },
            Some(ref mut left_child) => {
                left_child.add_child_node(new_node);
            }
        }
    }

    pub fn has_children(node: &Node<T>) -> bool {
        match node.left_child {
            Some(_) => true,
            _ => {
                match node.right_child {
                    Some(_) => true,
                    _ => false
                }
            }
        }
    }

    pub fn visit_in_order(&self, visitor: &fn(&Node<T>)) {
        match self.left_child {
            Some (ref n) => {
                n.visit_in_order(visitor);
            },
            _ => {}
        }

        visitor(self);

        match self.right_child {
            Some (ref n) => {
                n.visit_in_order(visitor);
            },
            _ => {}
        }
    }
}

pub impl<T:Ord> Tree<T> {
    pub fn new () -> Tree<T> {
        Tree {
            root: None
        }
    }

    fn insert_value (&mut self, value: T) {
        let new_node = ~Node::new(value);
        self.insert_node(new_node);
    }

    fn insert_node (&mut self, new_node: ~Node<T>) {
        match self.root {
            None => {
                self.root = Some(new_node);
            },
            Some(ref mut n) => {
                n.add_child_node(new_node);
            }
        }
    }

    fn visit_in_order (&self, visitor: &fn(&Node<T>)) {
        match self.root {
            Some(ref n) => {
                n.visit_in_order(visitor);
            },
            _ => {
            }
        }
    }
}

fn main () {
    let mut myTree: Tree<int> = Tree::new();

    myTree.insert_value(3);
    myTree.insert_value(2);
    myTree.insert_value(4);
    myTree.insert_value(0);

    myTree.visit_in_order(|n| {
                          std::io::println(fmt!("%d", n.key));
                          });
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/number-of-submatrices-that-sum-to-target/
pub fn num_submatrix_sum_target(matrix: Vec<Vec<i32>>, target: i32) -> i32 {
    let mut answer = 0;
    let max_rows = matrix.len();
    let max_cols = if max_rows > 0 { matrix[0].len() } else { 0 };
    let mut prefix_sums = vec![vec![0; max_cols]; max_cols];
    for row in 0..max_rows {
        for col in 0..max_cols {
            prefix_sums[row][col] = if col == 0 {
                matrix[row][col]
            } else {
                prefix_sums[row][col - 1] + matrix[row][col]
            };
        }
    }
    for row1 in 0..max_rows {
        for col1 in 0..max_cols {
            for row2 in row1..max_rows {
                for col2 in col1..max_cols {
                    todo!()
                }
            }
        }
    }
    answer
}

fn main() {
    // println!(
    //     "{}",
    //     num_submatrix_sum_target(vec![vec![0, 0, 0], vec![1, -1, 1], vec![0, 1, 0]], 0)
    // ); // 14
    // println!(
    //     "{}",
    //     num_submatrix_sum_target(vec![vec![0, 1, 0], vec![1, 1, 1], vec![0, 1, 0]], 0)
    // ); // 4
    // println!(
    //     "{}",
    //     num_submatrix_sum_target(vec![vec![1, -1], vec![-1, 1]], 0)
    // ); // 5
    // println!("{}", num_submatrix_sum_target(vec![vec![904]], 0)); // 0
    println!(
        "{}",
        num_submatrix_sum_target(
            vec![
                vec![0, 0, 0, 1, 1],
                vec![1, 1, 1, 0, 1],
                vec![1, 1, 1, 1, 0],
                vec![0, 0, 0, 1, 0],
                vec![0, 0, 0, 1, 1]
            ],
            0
        )
    ); // 28
}
<commit_msg>Update problem 1074<commit_after>// https://leetcode.com/problems/number-of-submatrices-that-sum-to-target/
pub fn num_submatrix_sum_target(matrix: Vec<Vec<i32>>, target: i32) -> i32 {
    let mut answer = 0;
    let max_rows = matrix.len();
    let max_cols = if max_rows > 0 { matrix[0].len() } else { 0 };
    let mut prefix_sums = vec![vec![0; max_cols]; max_rows];
    for row in 0..max_rows {
        for col in 0..max_cols {
            prefix_sums[row][col] = if col == 0 {
                matrix[row][col]
            } else {
                prefix_sums[row][col - 1] + matrix[row][col]
            };
        }
    }
    for row1 in 0..max_rows {
        for col1 in 0..max_cols {
            for row2 in row1..max_rows {
                for col2 in col1..max_cols {
                    let mut sum = 0;
                    for i in row1..=row2 {
                        sum += if col1 == 0 {
                            prefix_sums[i][col2]
                        } else {
                            prefix_sums[i][col2] - prefix_sums[i][col1 - 1]
                        };
                    }
                    if sum == target {
                        answer += 1;
                    }
                }
            }
        }
    }
    answer
}

fn main() {
    println!(
        "{}",
        num_submatrix_sum_target(vec![vec![0, 0, 0], vec![1, -1, 1], vec![0, 1, 0]], 0)
    ); // 14
    println!(
        "{}",
        num_submatrix_sum_target(vec![vec![0, 1, 0], vec![1, 1, 1], vec![0, 1, 0]], 0)
    ); // 4
    println!(
        "{}",
        num_submatrix_sum_target(vec![vec![1, -1], vec![-1, 1]], 0)
    ); // 5
    println!("{}", num_submatrix_sum_target(vec![vec![904]], 0)); // 0
    println!(
        "{}",
        num_submatrix_sum_target(
            vec![
                vec![0, 0, 0, 1, 1],
                vec![1, 1, 1, 0, 1],
                vec![1, 1, 1, 1, 0],
                vec![0, 0, 0, 1, 0],
                vec![0, 0, 0, 1, 1]
            ],
            0
        )
    ); // 28
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/the-number-of-weak-characters-in-the-game/
pub fn number_of_weak_characters(properties: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        number_of_weak_characters(vec![vec![5, 5], vec![6, 3], vec![3, 6]])
    ); // 0
    println!(
        "{}",
        number_of_weak_characters(vec![vec![2, 2], vec![3, 3]])
    ); // 1
    println!(
        "{}",
        number_of_weak_characters(vec![vec![1, 5], vec![10, 4], vec![4, 3]])
    ); // 1
}
<commit_msg>Update problem 1996<commit_after>// https://leetcode.com/problems/the-number-of-weak-characters-in-the-game/
pub fn number_of_weak_characters(properties: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        number_of_weak_characters(vec![vec![5, 5], vec![6, 3], vec![3, 6]])
    ); // 0
    println!(
        "{}",
        number_of_weak_characters(vec![vec![2, 2], vec![3, 3]])
    ); // 1
    println!(
        "{}",
        number_of_weak_characters(vec![vec![1, 5], vec![10, 4], vec![4, 3]])
    ); // 1
    println!(
        "{}",
        number_of_weak_characters(vec![vec![1, 5], vec![10, 4], vec![4, 3], vec![5, 5]])
    ); // 1
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/maximum-number-of-pairs-in-array/
pub fn number_of_pairs(nums: Vec<i32>) -> Vec<i32> {
    todo!()
}

fn main() {
    println!("{:?}", number_of_pairs(vec![1, 3, 2, 1, 3, 2, 2])); // [3,1]
    println!("{:?}", number_of_pairs(vec![1, 1])); // [1,0]
    println!("{:?}", number_of_pairs(vec![0])); // [0,1]
}
<commit_msg>Solve problem 2341<commit_after>use std::collections::HashMap;

// https://leetcode.com/problems/maximum-number-of-pairs-in-array/
pub fn number_of_pairs(nums: Vec<i32>) -> Vec<i32> {
    let mut answer = vec![0; 2];
    let mut map: HashMap<i32, i32> = HashMap::new();
    for i in nums {
        if !map.contains_key(&i) {
            map.insert(i, 1);
        } else {
            map.insert(i, map.get(&i).unwrap() + 1);
        }
    }
    let mut num_pairs = 0;
    let mut num_leftover = 0;
    for (_, count) in map.iter() {
        num_pairs += count / 2;
        num_leftover += count % 2;
    }
    answer[0] = num_pairs;
    answer[1] = num_leftover;
    answer
}

fn main() {
    println!("{:?}", number_of_pairs(vec![1, 3, 2, 1, 3, 2, 2])); // [3,1]
    println!("{:?}", number_of_pairs(vec![1, 1])); // [1,0]
    println!("{:?}", number_of_pairs(vec![0])); // [0,1]
}
<|endoftext|>


<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Boden Garman <bpgarman@gmail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) fpath

#[macro_use]
extern crate uucore;

mod count_bytes;
mod countable;
use count_bytes::count_bytes_fast;
use countable::WordCountable;

use clap::{App, Arg, ArgMatches};
use thiserror::Error;

use std::cmp::max;
use std::fs::File;
use std::io::{self, Write};
use std::ops::{Add, AddAssign};
use std::path::Path;
use std::str::from_utf8;

#[derive(Error, Debug)]
pub enum WcError {
    #[error("{0}")]
    Io(#[from] io::Error),
    #[error("Expected a file, found directory {0}")]
    IsDirectory(String),
}

type WcResult<T> = Result<T, WcError>;

struct Settings {
    show_bytes: bool,
    show_chars: bool,
    show_lines: bool,
    show_words: bool,
    show_max_line_length: bool,
}

impl Settings {
    fn new(matches: &ArgMatches) -> Settings {
        let settings = Settings {
            show_bytes: matches.is_present(options::BYTES),
            show_chars: matches.is_present(options::CHAR),
            show_lines: matches.is_present(options::LINES),
            show_words: matches.is_present(options::WORDS),
            show_max_line_length: matches.is_present(options::MAX_LINE_LENGTH),
        };

        if settings.show_bytes
            || settings.show_chars
            || settings.show_lines
            || settings.show_words
            || settings.show_max_line_length
        {
            return settings;
        }

        Settings {
            show_bytes: true,
            show_chars: false,
            show_lines: true,
            show_words: true,
            show_max_line_length: false,
        }
    }

    fn number_enabled(&self) -> u32 {
        let mut result = 0;
        result += self.show_bytes as u32;
        result += self.show_chars as u32;
        result += self.show_lines as u32;
        result += self.show_max_line_length as u32;
        result += self.show_words as u32;
        result
    }
}

#[derive(Debug, Default, Copy, Clone)]
struct WordCount {
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

impl Add for WordCount {
    type Output = Self;

    fn add(self, other: Self) -> Self {
        Self {
            bytes: self.bytes + other.bytes,
            chars: self.chars + other.chars,
            lines: self.lines + other.lines,
            words: self.words + other.words,
            max_line_length: max(self.max_line_length, other.max_line_length),
        }
    }
}

impl AddAssign for WordCount {
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl WordCount {
    fn with_title(self, title: &str) -> TitledWordCount {
        TitledWordCount { title, count: self }
    }
}

/// This struct supplements the actual word count with a title that is displayed
/// to the user at the end of the program.
/// The reason we don't simply include title in the `WordCount` struct is that
/// it would result in unneccesary copying of `String`.
#[derive(Debug, Default, Clone)]
struct TitledWordCount<'a> {
    title: &'a str,
    count: WordCount,
}

static ABOUT: &str = "Display newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified.";
static VERSION: &str = env!("CARGO_PKG_VERSION");

pub mod options {
    pub static BYTES: &str = "bytes";
    pub static CHAR: &str = "chars";
    pub static LINES: &str = "lines";
    pub static MAX_LINE_LENGTH: &str = "max-line-length";
    pub static WORDS: &str = "words";
}

static ARG_FILES: &str = "files";

fn get_usage() -> String {
    format!(
        "{0} [OPTION]... [FILE]...
 With no FILE, or when FILE is -, read standard input.",
        executable!()
    )
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = get_usage();

    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .arg(
            Arg::with_name(options::BYTES)
                .short("c")
                .long(options::BYTES)
                .help("print the byte counts"),
        )
        .arg(
            Arg::with_name(options::CHAR)
                .short("m")
                .long(options::CHAR)
                .help("print the character counts"),
        )
        .arg(
            Arg::with_name(options::LINES)
                .short("l")
                .long(options::LINES)
                .help("print the newline counts"),
        )
        .arg(
            Arg::with_name(options::MAX_LINE_LENGTH)
                .short("L")
                .long(options::MAX_LINE_LENGTH)
                .help("print the length of the longest line"),
        )
        .arg(
            Arg::with_name(options::WORDS)
                .short("w")
                .long(options::WORDS)
                .help("print the word counts"),
        )
        .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
        .get_matches_from(args);

    let mut files: Vec<String> = matches
        .values_of(ARG_FILES)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();

    if files.is_empty() {
        files.push("-".to_owned());
    }

    let settings = Settings::new(&matches);

    if wc(files, &settings).is_ok() {
        0
    } else {
        1
    }
}

const CR: u8 = b'\r';
const LF: u8 = b'\n';
const SPACE: u8 = b' ';
const TAB: u8 = b'\t';
const SYN: u8 = 0x16_u8;
const FF: u8 = 0x0C_u8;

#[inline(always)]
fn is_word_separator(byte: u8) -> bool {
    byte == SPACE || byte == TAB || byte == CR || byte == SYN || byte == FF
}

fn word_count_from_reader<T: WordCountable>(
    mut reader: T,
    settings: &Settings,
    path: &str,
) -> WcResult<WordCount> {
    let only_count_bytes = settings.show_bytes
        && (!(settings.show_chars
            || settings.show_lines
            || settings.show_max_line_length
            || settings.show_words));
    if only_count_bytes {
        return Ok(WordCount {
            bytes: count_bytes_fast(&mut reader)?,
            ..WordCount::default()
        });
    }

    // we do not need to decode the byte stream if we're only counting bytes/newlines
    let decode_chars = settings.show_chars || settings.show_words || settings.show_max_line_length;

    let mut line_count: usize = 0;
    let mut word_count: usize = 0;
    let mut byte_count: usize = 0;
    let mut char_count: usize = 0;
    let mut longest_line_length: usize = 0;
    let mut ends_lf: bool;

    // reading from a TTY seems to raise a condition on, rather than return Some(0) like a file.
    // hence the option wrapped in a result here
    for line_result in reader.lines() {
        let raw_line = match line_result {
            Ok(l) => l,
            Err(e) => {
                show_warning!("Error while reading {}: {}", path, e);
                continue;
            }
        };

        // GNU 'wc' only counts lines that end in LF as lines
        ends_lf = *raw_line.last().unwrap() == LF;
        line_count += ends_lf as usize;

        byte_count += raw_line.len();

        if decode_chars {
            // try and convert the bytes to UTF-8 first
            let current_char_count;
            match from_utf8(&raw_line[..]) {
                Ok(line) => {
                    word_count += line.split_whitespace().count();
                    current_char_count = line.chars().count();
                }
                Err(..) => {
                    word_count += raw_line.split(|&x| is_word_separator(x)).count();
                    current_char_count = raw_line.iter().filter(|c| c.is_ascii()).count()
                }
            }
            char_count += current_char_count;
            if current_char_count > longest_line_length {
                // -L is a GNU 'wc' extension so same behavior on LF
                longest_line_length = current_char_count - (ends_lf as usize);
            }
        }
    }

    Ok(WordCount {
        bytes: byte_count,
        chars: char_count,
        lines: line_count,
        words: word_count,
        max_line_length: longest_line_length,
    })
}

fn word_count_from_path(path: &str, settings: &Settings) -> WcResult<WordCount> {
    if path == "-" {
        let stdin = io::stdin();
        let stdin_lock = stdin.lock();
        word_count_from_reader(stdin_lock, settings, path)
    } else {
        let path_obj = Path::new(path);
        if path_obj.is_dir() {
            Err(WcError::IsDirectory(path.to_owned()))
        } else {
            let file = File::open(path)?;
            word_count_from_reader(file, settings, path)
        }
    }
}

fn wc(files: Vec<String>, settings: &Settings) -> Result<(), u32> {
    let mut total_word_count = WordCount::default();
    let mut results = vec![];
    let mut max_width: usize = 0;
    let mut error_count = 0;

    let num_files = files.len();

    for path in &files {
        let word_count = word_count_from_path(&path, settings).unwrap_or_else(|err| {
            show_error!("{}", err);
            error_count += 1;
            WordCount::default()
        });
        // Compute the number of digits needed to display the number
        // of bytes in the file. Even if the settings indicate that we
        // won't *display* the number of bytes, we still use the
        // number of digits in the byte count as the width when
        // formatting each count as a string for output.
        max_width = max(max_width, word_count.bytes.to_string().len());
        total_word_count += word_count;
        results.push(word_count.with_title(path));
    }

    for result in &results {
        if let Err(err) = print_stats(settings, &result, max_width) {
            show_warning!("failed to print result for {}: {}", result.title, err);
            error_count += 1;
        }
    }

    if num_files > 1 {
        let total_result = total_word_count.with_title("total");
        if let Err(err) = print_stats(settings, &total_result, max_width) {
            show_warning!("failed to print total: {}", err);
            error_count += 1;
        }
    }

    if error_count == 0 {
        Ok(())
    } else {
        Err(error_count)
    }
}

fn print_stats(
    settings: &Settings,
    result: &TitledWordCount,
    mut min_width: usize,
) -> WcResult<()> {
    let stdout = io::stdout();
    let mut stdout_lock = stdout.lock();

    if settings.number_enabled() <= 1 {
        // Prevent a leading space in case we only need to display a single
        // number.
        min_width = 0;
    }

    let mut is_first: bool = true;

    if settings.show_lines {
        if is_first {
            write!(stdout_lock, "{:1$}", result.count.lines, min_width)?;
        } else {
            write!(stdout_lock, " {:1$}", result.count.lines, min_width)?;
        }
        is_first = false;
    }
    if settings.show_words {
        if is_first {
            write!(stdout_lock, "{:1$}", result.count.words, min_width)?;
        } else {
            write!(stdout_lock, " {:1$}", result.count.words, min_width)?;
        }
        is_first = false;
    }
    if settings.show_bytes {
        if is_first {
            write!(stdout_lock, "{:1$}", result.count.bytes, min_width)?;
        } else {
            write!(stdout_lock, " {:1$}", result.count.bytes, min_width)?;
        }
        is_first = false;
    }
    if settings.show_chars {
        if is_first {
            write!(stdout_lock, "{:1$}", result.count.chars, min_width)?;
        } else {
            write!(stdout_lock, " {:1$}", result.count.chars, min_width)?;
        }
        is_first = false;
    }
    if settings.show_max_line_length {
        if is_first {
            write!(
                stdout_lock,
                "{:1$}",
                result.count.max_line_length, min_width
            )?;
        } else {
            write!(
                stdout_lock,
                " {:1$}",
                result.count.max_line_length, min_width
            )?;
        }
    }

    if result.title == "-" {
        writeln!(stdout_lock)?;
    } else {
        writeln!(stdout_lock, " {}", result.title)?;
    }

    Ok(())
}
<commit_msg>fixup! wc: rm leading space when printing multiple counts<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Boden Garman <bpgarman@gmail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) fpath

#[macro_use]
extern crate uucore;

mod count_bytes;
mod countable;
use count_bytes::count_bytes_fast;
use countable::WordCountable;

use clap::{App, Arg, ArgMatches};
use thiserror::Error;

use std::cmp::max;
use std::fs::File;
use std::io::{self, Write};
use std::ops::{Add, AddAssign};
use std::path::Path;
use std::str::from_utf8;

#[derive(Error, Debug)]
pub enum WcError {
    #[error("{0}")]
    Io(#[from] io::Error),
    #[error("Expected a file, found directory {0}")]
    IsDirectory(String),
}

type WcResult<T> = Result<T, WcError>;

struct Settings {
    show_bytes: bool,
    show_chars: bool,
    show_lines: bool,
    show_words: bool,
    show_max_line_length: bool,
}

impl Settings {
    fn new(matches: &ArgMatches) -> Settings {
        let settings = Settings {
            show_bytes: matches.is_present(options::BYTES),
            show_chars: matches.is_present(options::CHAR),
            show_lines: matches.is_present(options::LINES),
            show_words: matches.is_present(options::WORDS),
            show_max_line_length: matches.is_present(options::MAX_LINE_LENGTH),
        };

        if settings.show_bytes
            || settings.show_chars
            || settings.show_lines
            || settings.show_words
            || settings.show_max_line_length
        {
            return settings;
        }

        Settings {
            show_bytes: true,
            show_chars: false,
            show_lines: true,
            show_words: true,
            show_max_line_length: false,
        }
    }

    fn number_enabled(&self) -> u32 {
        let mut result = 0;
        result += self.show_bytes as u32;
        result += self.show_chars as u32;
        result += self.show_lines as u32;
        result += self.show_max_line_length as u32;
        result += self.show_words as u32;
        result
    }
}

#[derive(Debug, Default, Copy, Clone)]
struct WordCount {
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

impl Add for WordCount {
    type Output = Self;

    fn add(self, other: Self) -> Self {
        Self {
            bytes: self.bytes + other.bytes,
            chars: self.chars + other.chars,
            lines: self.lines + other.lines,
            words: self.words + other.words,
            max_line_length: max(self.max_line_length, other.max_line_length),
        }
    }
}

impl AddAssign for WordCount {
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl WordCount {
    fn with_title(self, title: &str) -> TitledWordCount {
        TitledWordCount { title, count: self }
    }
}

/// This struct supplements the actual word count with a title that is displayed
/// to the user at the end of the program.
/// The reason we don't simply include title in the `WordCount` struct is that
/// it would result in unneccesary copying of `String`.
#[derive(Debug, Default, Clone)]
struct TitledWordCount<'a> {
    title: &'a str,
    count: WordCount,
}

static ABOUT: &str = "Display newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified.";
static VERSION: &str = env!("CARGO_PKG_VERSION");

pub mod options {
    pub static BYTES: &str = "bytes";
    pub static CHAR: &str = "chars";
    pub static LINES: &str = "lines";
    pub static MAX_LINE_LENGTH: &str = "max-line-length";
    pub static WORDS: &str = "words";
}

static ARG_FILES: &str = "files";

fn get_usage() -> String {
    format!(
        "{0} [OPTION]... [FILE]...
 With no FILE, or when FILE is -, read standard input.",
        executable!()
    )
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = get_usage();

    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .arg(
            Arg::with_name(options::BYTES)
                .short("c")
                .long(options::BYTES)
                .help("print the byte counts"),
        )
        .arg(
            Arg::with_name(options::CHAR)
                .short("m")
                .long(options::CHAR)
                .help("print the character counts"),
        )
        .arg(
            Arg::with_name(options::LINES)
                .short("l")
                .long(options::LINES)
                .help("print the newline counts"),
        )
        .arg(
            Arg::with_name(options::MAX_LINE_LENGTH)
                .short("L")
                .long(options::MAX_LINE_LENGTH)
                .help("print the length of the longest line"),
        )
        .arg(
            Arg::with_name(options::WORDS)
                .short("w")
                .long(options::WORDS)
                .help("print the word counts"),
        )
        .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
        .get_matches_from(args);

    let mut files: Vec<String> = matches
        .values_of(ARG_FILES)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();

    if files.is_empty() {
        files.push("-".to_owned());
    }

    let settings = Settings::new(&matches);

    if wc(files, &settings).is_ok() {
        0
    } else {
        1
    }
}

const CR: u8 = b'\r';
const LF: u8 = b'\n';
const SPACE: u8 = b' ';
const TAB: u8 = b'\t';
const SYN: u8 = 0x16_u8;
const FF: u8 = 0x0C_u8;

#[inline(always)]
fn is_word_separator(byte: u8) -> bool {
    byte == SPACE || byte == TAB || byte == CR || byte == SYN || byte == FF
}

fn word_count_from_reader<T: WordCountable>(
    mut reader: T,
    settings: &Settings,
    path: &str,
) -> WcResult<WordCount> {
    let only_count_bytes = settings.show_bytes
        && (!(settings.show_chars
            || settings.show_lines
            || settings.show_max_line_length
            || settings.show_words));
    if only_count_bytes {
        return Ok(WordCount {
            bytes: count_bytes_fast(&mut reader)?,
            ..WordCount::default()
        });
    }

    // we do not need to decode the byte stream if we're only counting bytes/newlines
    let decode_chars = settings.show_chars || settings.show_words || settings.show_max_line_length;

    let mut line_count: usize = 0;
    let mut word_count: usize = 0;
    let mut byte_count: usize = 0;
    let mut char_count: usize = 0;
    let mut longest_line_length: usize = 0;
    let mut ends_lf: bool;

    // reading from a TTY seems to raise a condition on, rather than return Some(0) like a file.
    // hence the option wrapped in a result here
    for line_result in reader.lines() {
        let raw_line = match line_result {
            Ok(l) => l,
            Err(e) => {
                show_warning!("Error while reading {}: {}", path, e);
                continue;
            }
        };

        // GNU 'wc' only counts lines that end in LF as lines
        ends_lf = *raw_line.last().unwrap() == LF;
        line_count += ends_lf as usize;

        byte_count += raw_line.len();

        if decode_chars {
            // try and convert the bytes to UTF-8 first
            let current_char_count;
            match from_utf8(&raw_line[..]) {
                Ok(line) => {
                    word_count += line.split_whitespace().count();
                    current_char_count = line.chars().count();
                }
                Err(..) => {
                    word_count += raw_line.split(|&x| is_word_separator(x)).count();
                    current_char_count = raw_line.iter().filter(|c| c.is_ascii()).count()
                }
            }
            char_count += current_char_count;
            if current_char_count > longest_line_length {
                // -L is a GNU 'wc' extension so same behavior on LF
                longest_line_length = current_char_count - (ends_lf as usize);
            }
        }
    }

    Ok(WordCount {
        bytes: byte_count,
        chars: char_count,
        lines: line_count,
        words: word_count,
        max_line_length: longest_line_length,
    })
}

fn word_count_from_path(path: &str, settings: &Settings) -> WcResult<WordCount> {
    if path == "-" {
        let stdin = io::stdin();
        let stdin_lock = stdin.lock();
        word_count_from_reader(stdin_lock, settings, path)
    } else {
        let path_obj = Path::new(path);
        if path_obj.is_dir() {
            Err(WcError::IsDirectory(path.to_owned()))
        } else {
            let file = File::open(path)?;
            word_count_from_reader(file, settings, path)
        }
    }
}

fn wc(files: Vec<String>, settings: &Settings) -> Result<(), u32> {
    let mut total_word_count = WordCount::default();
    let mut results = vec![];
    let mut max_width: usize = 0;
    let mut error_count = 0;

    let num_files = files.len();

    for path in &files {
        let word_count = word_count_from_path(&path, settings).unwrap_or_else(|err| {
            show_error!("{}", err);
            error_count += 1;
            WordCount::default()
        });
        // Compute the number of digits needed to display the number
        // of bytes in the file. Even if the settings indicate that we
        // won't *display* the number of bytes, we still use the
        // number of digits in the byte count as the width when
        // formatting each count as a string for output.
        max_width = max(max_width, word_count.bytes.to_string().len());
        total_word_count += word_count;
        results.push(word_count.with_title(path));
    }

    for result in &results {
        if let Err(err) = print_stats(settings, &result, max_width) {
            show_warning!("failed to print result for {}: {}", result.title, err);
            error_count += 1;
        }
    }

    if num_files > 1 {
        let total_result = total_word_count.with_title("total");
        if let Err(err) = print_stats(settings, &total_result, max_width) {
            show_warning!("failed to print total: {}", err);
            error_count += 1;
        }
    }

    if error_count == 0 {
        Ok(())
    } else {
        Err(error_count)
    }
}

fn print_stats(
    settings: &Settings,
    result: &TitledWordCount,
    mut min_width: usize,
) -> WcResult<()> {
    let stdout = io::stdout();
    let mut stdout_lock = stdout.lock();

    if settings.number_enabled() <= 1 {
        // Prevent a leading space in case we only need to display a single
        // number.
        min_width = 0;
    }

    let mut is_first: bool = true;

    if settings.show_lines {
        if !is_first {
            write!(stdout_lock, " ")?;
        }
        write!(stdout_lock, "{:1$}", result.count.lines, min_width)?;
        is_first = false;
    }
    if settings.show_words {
        if !is_first {
            write!(stdout_lock, " ")?;
        }
        write!(stdout_lock, "{:1$}", result.count.words, min_width)?;
        is_first = false;
    }
    if settings.show_bytes {
        if !is_first {
            write!(stdout_lock, " ")?;
        }
        write!(stdout_lock, "{:1$}", result.count.bytes, min_width)?;
        is_first = false;
    }
    if settings.show_chars {
        if !is_first {
            write!(stdout_lock, " ")?;
        }
        write!(stdout_lock, "{:1$}", result.count.chars, min_width)?;
        is_first = false;
    }
    if settings.show_max_line_length {
        if !is_first {
            write!(stdout_lock, " ")?;
        }
        write!(
            stdout_lock,
            "{:1$}",
            result.count.max_line_length, min_width
        )?;
    }

    if result.title == "-" {
        writeln!(stdout_lock)?;
    } else {
        writeln!(stdout_lock, " {}", result.title)?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>//! Tidy check to enforce rules about platform-specific code in std.
//!
//! This is intended to maintain existing standards of code
//! organization in hopes that the standard library will continue to
//! be refactored to isolate platform-specific bits, making porting
//! easier; where "standard library" roughly means "all the
//! dependencies of the std and test crates".
//!
//! This generally means placing restrictions on where `cfg(unix)`,
//! `cfg(windows)`, `cfg(target_os)` and `cfg(target_env)` may appear,
//! the basic objective being to isolate platform-specific code to the
//! platform-specific `std::sys` modules, and to the allocation,
//! unwinding, and libc crates.
//!
//! Following are the basic rules, though there are currently
//! exceptions:
//!
//! - core may not have platform-specific code.
//! - libpanic_abort may have platform-specific code.
//! - libpanic_unwind may have platform-specific code.
//! - libunwind may have platform-specific code.
//! - other crates in the std facade may not.
//! - std may have platform-specific code in the following places:
//!   - `sys/unix/`
//!   - `sys/windows/`
//!   - `os/`
//!
//! `std/sys_common` should _not_ contain platform-specific code.
//! Finally, because std contains tests with platform-specific
//! `ignore` attributes, once the parser encounters `mod tests`,
//! platform-specific cfgs are allowed. Not sure yet how to deal with
//! this in the long term.

use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::iter::Iterator;

// Paths that may contain platform-specific code.
const EXCEPTION_PATHS: &[&str] = &[
    // std crates
    "src/libpanic_abort",
    "src/libpanic_unwind",
    "src/libunwind",
    // black_box implementation is LLVM-version specific and it uses
    // target_os to tell targets with different LLVM-versions appart
    // (e.g. `wasm32-unknown-emscripten` vs `wasm32-unknown-unknown`):
    "src/libcore/hint.rs",
    "src/libstd/sys/", // Platform-specific code for std lives here.
                       // This has the trailing slash so that sys_common is not excepted.
    "src/libstd/os", // Platform-specific public interfaces
    "src/rtstartup", // Not sure what to do about this. magic stuff for mingw

    // temporary exceptions
    "src/libstd/lib.rs",
    "src/libstd/path.rs",
    "src/libstd/f32.rs",
    "src/libstd/f64.rs",
    // Integration test for platform-specific run-time feature detection:
    "src/libstd/tests/run-time-detect.rs" ,
    "src/libstd/net/test.rs",
    "src/libstd/sys_common/mod.rs",
    "src/libstd/sys_common/net.rs",
    "src/libstd/sys_common/backtrace.rs",
    "src/libterm", // Not sure how to make this crate portable, but test crate needs it.
    "src/libtest", // Probably should defer to unstable `std::sys` APIs.
    "src/libstd/sync/mpsc", // some tests are only run on non-emscripten

    // std testing crates, okay for now at least
    "src/libcore/tests",
    "src/liballoc/tests/lib.rs",

    // The `VaList` implementation must have platform specific code.
    // The Windows implementation of a `va_list` is always a character
    // pointer regardless of the target architecture. As a result,
    // we must use `#[cfg(windows)]` to conditionally compile the
    // correct `VaList` structure for windows.
    "src/libcore/ffi.rs",

    // non-std crates
    "src/test",
    "src/tools",
    "src/librustc",
    "src/librustdoc",
    "src/libsyntax",
    "src/bootstrap",
];

pub fn check(path: &Path, bad: &mut bool) {
    let mut contents = String::new();
    // Sanity check that the complex parsing here works.
    let mut saw_target_arch = false;
    let mut saw_cfg_bang = false;
    super::walk(path, &mut super::filter_dirs, &mut |file| {
        let filestr = file.to_string_lossy().replace("\\", "/");
        if !filestr.ends_with(".rs") { return }

        let is_exception_path = EXCEPTION_PATHS.iter().any(|s| filestr.contains(&**s));
        if is_exception_path { return }

        check_cfgs(&mut contents, &file, bad, &mut saw_target_arch, &mut saw_cfg_bang);
    });

    assert!(saw_target_arch);
    assert!(saw_cfg_bang);
}

fn check_cfgs(contents: &mut String, file: &Path,
              bad: &mut bool, saw_target_arch: &mut bool, saw_cfg_bang: &mut bool) {
    contents.truncate(0);
    t!(t!(File::open(file), file).read_to_string(contents));

    // For now it's ok to have platform-specific code after 'mod tests'.
    let mod_tests_idx = find_test_mod(contents);
    let contents = &contents[..mod_tests_idx];
    // Pull out all `cfg(...)` and `cfg!(...)` strings.
    let cfgs = parse_cfgs(contents);

    let mut line_numbers: Option<Vec<usize>> = None;
    let mut err = |idx: usize, cfg: &str| {
        if line_numbers.is_none() {
            line_numbers = Some(contents.match_indices('\n').map(|(i, _)| i).collect());
        }
        let line_numbers = line_numbers.as_ref().expect("");
        let line = match line_numbers.binary_search(&idx) {
            Ok(_) => unreachable!(),
            Err(i) => i + 1
        };
        tidy_error!(bad, "{}:{}: platform-specific cfg: {}", file.display(), line, cfg);
    };

    for (idx, cfg) in cfgs {
        // Sanity check that the parsing here works.
        if !*saw_target_arch && cfg.contains("target_arch") { *saw_target_arch = true }
        if !*saw_cfg_bang && cfg.contains("cfg!") { *saw_cfg_bang = true }

        let contains_platform_specific_cfg =
            cfg.contains("target_os")
            || cfg.contains("target_env")
            || cfg.contains("target_vendor")
            || cfg.contains("unix")
            || cfg.contains("windows");

        if !contains_platform_specific_cfg { continue }

        let preceeded_by_doc_comment = {
            let pre_contents = &contents[..idx];
            let pre_newline = pre_contents.rfind('\n');
            let pre_doc_comment = pre_contents.rfind("///");
            match (pre_newline, pre_doc_comment) {
                (Some(n), Some(c)) => n < c,
                (None, Some(_)) => true,
                (_, None) => false,
            }
        };

        if preceeded_by_doc_comment { continue }

        err(idx, cfg);
    }
}

fn find_test_mod(contents: &str) -> usize {
    if let Some(mod_tests_idx) = contents.find("mod tests") {
        // Also capture a previous line indicating that "mod tests" is cfg'd out.
        let prev_newline_idx = contents[..mod_tests_idx].rfind('\n').unwrap_or(mod_tests_idx);
        let prev_newline_idx = contents[..prev_newline_idx].rfind('\n');
        if let Some(nl) = prev_newline_idx {
            let prev_line = &contents[nl + 1 .. mod_tests_idx];
            if prev_line.contains("cfg(all(test, not(target_os")
                || prev_line.contains("cfg(all(test, not(any(target_os") {
                nl
            } else {
                mod_tests_idx
            }
        } else {
            mod_tests_idx
        }
    } else {
        contents.len()
    }
}

fn parse_cfgs<'a>(contents: &'a str) -> Vec<(usize, &'a str)> {
    let candidate_cfgs = contents.match_indices("cfg");
    let candidate_cfg_idxs = candidate_cfgs.map(|(i, _)| i);
    // This is puling out the indexes of all "cfg" strings
    // that appear to be tokens followed by a parenthesis.
    let cfgs = candidate_cfg_idxs.filter(|i| {
        let pre_idx = i.saturating_sub(*i);
        let succeeds_non_ident = !contents.as_bytes().get(pre_idx)
            .cloned()
            .map(char::from)
            .map(char::is_alphanumeric)
            .unwrap_or(false);
        let contents_after = &contents[*i..];
        let first_paren = contents_after.find('(');
        let paren_idx = first_paren.map(|ip| i + ip);
        let preceeds_whitespace_and_paren = paren_idx.map(|ip| {
            let maybe_space = &contents[*i + "cfg".len() .. ip];
            maybe_space.chars().all(|c| char::is_whitespace(c) || c == '!')
        }).unwrap_or(false);

        succeeds_non_ident && preceeds_whitespace_and_paren
    });

    cfgs.map(|i| {
        let mut depth = 0;
        let contents_from = &contents[i..];
        for (j, byte) in contents_from.bytes().enumerate() {
            match byte {
                b'(' => {
                    depth += 1;
                }
                b')' => {
                    depth -= 1;
                    if depth == 0 {
                        return (i, &contents_from[..=j]);
                    }
                }
                _ => { }
            }
        }

        unreachable!()
    }).collect()
}
<commit_msg>Do not panic in tidy on unbalanced parentheses in cfg's<commit_after>//! Tidy check to enforce rules about platform-specific code in std.
//!
//! This is intended to maintain existing standards of code
//! organization in hopes that the standard library will continue to
//! be refactored to isolate platform-specific bits, making porting
//! easier; where "standard library" roughly means "all the
//! dependencies of the std and test crates".
//!
//! This generally means placing restrictions on where `cfg(unix)`,
//! `cfg(windows)`, `cfg(target_os)` and `cfg(target_env)` may appear,
//! the basic objective being to isolate platform-specific code to the
//! platform-specific `std::sys` modules, and to the allocation,
//! unwinding, and libc crates.
//!
//! Following are the basic rules, though there are currently
//! exceptions:
//!
//! - core may not have platform-specific code.
//! - libpanic_abort may have platform-specific code.
//! - libpanic_unwind may have platform-specific code.
//! - libunwind may have platform-specific code.
//! - other crates in the std facade may not.
//! - std may have platform-specific code in the following places:
//!   - `sys/unix/`
//!   - `sys/windows/`
//!   - `os/`
//!
//! `std/sys_common` should _not_ contain platform-specific code.
//! Finally, because std contains tests with platform-specific
//! `ignore` attributes, once the parser encounters `mod tests`,
//! platform-specific cfgs are allowed. Not sure yet how to deal with
//! this in the long term.

use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::iter::Iterator;

// Paths that may contain platform-specific code.
const EXCEPTION_PATHS: &[&str] = &[
    // std crates
    "src/libpanic_abort",
    "src/libpanic_unwind",
    "src/libunwind",
    // black_box implementation is LLVM-version specific and it uses
    // target_os to tell targets with different LLVM-versions appart
    // (e.g. `wasm32-unknown-emscripten` vs `wasm32-unknown-unknown`):
    "src/libcore/hint.rs",
    "src/libstd/sys/", // Platform-specific code for std lives here.
                       // This has the trailing slash so that sys_common is not excepted.
    "src/libstd/os", // Platform-specific public interfaces
    "src/rtstartup", // Not sure what to do about this. magic stuff for mingw

    // temporary exceptions
    "src/libstd/lib.rs",
    "src/libstd/path.rs",
    "src/libstd/f32.rs",
    "src/libstd/f64.rs",
    // Integration test for platform-specific run-time feature detection:
    "src/libstd/tests/run-time-detect.rs" ,
    "src/libstd/net/test.rs",
    "src/libstd/sys_common/mod.rs",
    "src/libstd/sys_common/net.rs",
    "src/libstd/sys_common/backtrace.rs",
    "src/libterm", // Not sure how to make this crate portable, but test crate needs it.
    "src/libtest", // Probably should defer to unstable `std::sys` APIs.
    "src/libstd/sync/mpsc", // some tests are only run on non-emscripten

    // std testing crates, okay for now at least
    "src/libcore/tests",
    "src/liballoc/tests/lib.rs",

    // The `VaList` implementation must have platform specific code.
    // The Windows implementation of a `va_list` is always a character
    // pointer regardless of the target architecture. As a result,
    // we must use `#[cfg(windows)]` to conditionally compile the
    // correct `VaList` structure for windows.
    "src/libcore/ffi.rs",

    // non-std crates
    "src/test",
    "src/tools",
    "src/librustc",
    "src/librustdoc",
    "src/libsyntax",
    "src/bootstrap",
];

pub fn check(path: &Path, bad: &mut bool) {
    let mut contents = String::new();
    // Sanity check that the complex parsing here works.
    let mut saw_target_arch = false;
    let mut saw_cfg_bang = false;
    super::walk(path, &mut super::filter_dirs, &mut |file| {
        let filestr = file.to_string_lossy().replace("\\", "/");
        if !filestr.ends_with(".rs") { return }

        let is_exception_path = EXCEPTION_PATHS.iter().any(|s| filestr.contains(&**s));
        if is_exception_path { return }

        check_cfgs(&mut contents, &file, bad, &mut saw_target_arch, &mut saw_cfg_bang);
    });

    assert!(saw_target_arch);
    assert!(saw_cfg_bang);
}

fn check_cfgs(contents: &mut String, file: &Path,
              bad: &mut bool, saw_target_arch: &mut bool, saw_cfg_bang: &mut bool) {
    contents.truncate(0);
    t!(t!(File::open(file), file).read_to_string(contents));

    // For now it's ok to have platform-specific code after 'mod tests'.
    let mod_tests_idx = find_test_mod(contents);
    let contents = &contents[..mod_tests_idx];
    // Pull out all `cfg(...)` and `cfg!(...)` strings.
    let cfgs = parse_cfgs(contents);

    let mut line_numbers: Option<Vec<usize>> = None;
    let mut err = |idx: usize, cfg: &str| {
        if line_numbers.is_none() {
            line_numbers = Some(contents.match_indices('\n').map(|(i, _)| i).collect());
        }
        let line_numbers = line_numbers.as_ref().expect("");
        let line = match line_numbers.binary_search(&idx) {
            Ok(_) => unreachable!(),
            Err(i) => i + 1
        };
        tidy_error!(bad, "{}:{}: platform-specific cfg: {}", file.display(), line, cfg);
    };

    for (idx, cfg) in cfgs {
        // Sanity check that the parsing here works.
        if !*saw_target_arch && cfg.contains("target_arch") { *saw_target_arch = true }
        if !*saw_cfg_bang && cfg.contains("cfg!") { *saw_cfg_bang = true }

        let contains_platform_specific_cfg =
            cfg.contains("target_os")
            || cfg.contains("target_env")
            || cfg.contains("target_vendor")
            || cfg.contains("unix")
            || cfg.contains("windows");

        if !contains_platform_specific_cfg { continue }

        let preceeded_by_doc_comment = {
            let pre_contents = &contents[..idx];
            let pre_newline = pre_contents.rfind('\n');
            let pre_doc_comment = pre_contents.rfind("///");
            match (pre_newline, pre_doc_comment) {
                (Some(n), Some(c)) => n < c,
                (None, Some(_)) => true,
                (_, None) => false,
            }
        };

        if preceeded_by_doc_comment { continue }

        err(idx, cfg);
    }
}

fn find_test_mod(contents: &str) -> usize {
    if let Some(mod_tests_idx) = contents.find("mod tests") {
        // Also capture a previous line indicating that "mod tests" is cfg'd out.
        let prev_newline_idx = contents[..mod_tests_idx].rfind('\n').unwrap_or(mod_tests_idx);
        let prev_newline_idx = contents[..prev_newline_idx].rfind('\n');
        if let Some(nl) = prev_newline_idx {
            let prev_line = &contents[nl + 1 .. mod_tests_idx];
            if prev_line.contains("cfg(all(test, not(target_os")
                || prev_line.contains("cfg(all(test, not(any(target_os") {
                nl
            } else {
                mod_tests_idx
            }
        } else {
            mod_tests_idx
        }
    } else {
        contents.len()
    }
}

fn parse_cfgs<'a>(contents: &'a str) -> Vec<(usize, &'a str)> {
    let candidate_cfgs = contents.match_indices("cfg");
    let candidate_cfg_idxs = candidate_cfgs.map(|(i, _)| i);
    // This is puling out the indexes of all "cfg" strings
    // that appear to be tokens followed by a parenthesis.
    let cfgs = candidate_cfg_idxs.filter(|i| {
        let pre_idx = i.saturating_sub(*i);
        let succeeds_non_ident = !contents.as_bytes().get(pre_idx)
            .cloned()
            .map(char::from)
            .map(char::is_alphanumeric)
            .unwrap_or(false);
        let contents_after = &contents[*i..];
        let first_paren = contents_after.find('(');
        let paren_idx = first_paren.map(|ip| i + ip);
        let preceeds_whitespace_and_paren = paren_idx.map(|ip| {
            let maybe_space = &contents[*i + "cfg".len() .. ip];
            maybe_space.chars().all(|c| char::is_whitespace(c) || c == '!')
        }).unwrap_or(false);

        succeeds_non_ident && preceeds_whitespace_and_paren
    });

    cfgs.flat_map(|i| {
        let mut depth = 0;
        let contents_from = &contents[i..];
        for (j, byte) in contents_from.bytes().enumerate() {
            match byte {
                b'(' => {
                    depth += 1;
                }
                b')' => {
                    depth -= 1;
                    if depth == 0 {
                        return Some((i, &contents_from[..=j]));
                    }
                }
                _ => { }
            }
        }

        // if the parentheses are unbalanced just ignore this cfg -- it'll be caught when attempting
        // to run the compiler, and there's no real reason to lint it separately here
        None
    }).collect()
}
<|endoftext|>