r3bl-open-core icon indicating copy to clipboard operation
r3bl-open-core copied to clipboard

Add Hex and a Random Variant to Colors Enum

Open LuciAkirami opened this issue 1 year ago • 4 comments

Currently the Color Enum contains two variants, RBG and ANSI256. Apart from these, the following two variants can be added

  • Color::Hex(String) => This variant takes in Color as a Hex Format and converts it internally to RGB. Converting Hex to ANSI256 will not be required as RGB to ANSI256 function already exists.
  • Color::Random => Calling something like this AnsiStyledText { text: "Print a bold text w/ random color", style: &[ Style::Bold, Style::Foreground(Color::Random), ], }.println(); should print a bold text with a random color.

LuciAkirami avatar Oct 19 '23 18:10 LuciAkirami

Hey @nazmulidris. Can you assign this issue to me. By the way, should I be using rand crate for generating a random number?, or can we do something with any built-in crate to generate random numbers instead using an external dependency?

LuciAkirami avatar Oct 19 '23 18:10 LuciAkirami

@LuciAkirami Great question about rand crate. We have a ColorWheel implementation in the r3bl_tui crate (in the tui folder of the repo). Maybe take a look there to see if you can find how ColorWheel does it. If this is not enough information to go on, PLMK and I will dig deeper into this later & give you more info 👍🏽

nazmulidris avatar Oct 19 '23 21:10 nazmulidris

Hi @nazmulidris Working on this after a really long time, sorry for that (busy with office work dangg). So, I'm thinking of doing something like the below

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Color {
    Rgb(u8, u8, u8),
    Ansi256(u8),
    HexColor,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct HexColor<'a>{
    pub hex: &'a str,
}

mod hex_color_impl {
    use crate::{
                Ansi256Color,
                HexColor,
                RgbColor,
                TransformColor};
    
    use crate::convert::convert_hex_to_rgb;

    impl TransformColor for HexColor<'_> {
        /// Returns a [RgbColor] representation of the `self` color.
        fn as_rgb(&self) -> RgbColor {
            let rgb = convert_hex_to_rgb(&self.hex);
            RgbColor {
                red: rgb.red,
                green: rgb.green,
                blue: rgb.blue,
            }
        }

        /// Returns the index of a color in 256-color ANSI palette approximating the `self`
        /// color.
        fn as_ansi256(&self) -> Ansi256Color {
            let rgb = convert_hex_to_rgb(&self.hex);
            let rgb = RgbColor {
                red: rgb.red,
                green: rgb.green,
                blue: rgb.blue,
            };
            rgb.as_ansi256()
        }

        /// Returns the index of a color in 256-color ANSI palette approximating the `self`
        /// color as grayscale.
        fn as_grayscale(&self) -> Ansi256Color {
            let rgb = convert_hex_to_rgb(&self.hex);
            let rgb = RgbColor {
                red: rgb.red,
                green: rgb.green,
                blue: rgb.blue,
            };
            rgb.as_grayscale()
        }
    }
}

As for the conversion, below is the code

pub fn convert_hex_to_rgb(hex: &str) -> RgbColor {
    let hex = hex.trim_start_matches('#');
    let red = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0);
    let green = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0);
    let blue = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0);
    RgbColor { red, green, blue }
}

Yet to add checking if the given hex is valid or not. I just want to get a confirmation that I'm going in a right direction

LuciAkirami avatar Nov 19 '23 14:11 LuciAkirami

@LuciAkirami This is the right direction. Thanks for sharing the code. It looks good. Looking forward to the PR.

Also if you feel like the PR isn't ready and you want us to take a look at it, just mark it as draft and share it for review. We will understand that since it's marked as draft that the code is in very early stages of development 👍🏽

Also I put your code in Rust playground and it is pretty cool. I didn't know that HexColor could be Copy, since it owns a reference w/ lifetime 'a.

fn main() {
    let hex_string = "abc".to_string();
    let hex_string_ref = &hex_string;
    let it = HexColor { hex: hex_string_ref };
    
    takes_hex(it);

    std::mem::drop(it);

    println!("{:?}", it);
}


fn takes_hex(arg: HexColor) {
  // Drops arg!
}


#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct HexColor<'a>{
    pub hex: &'a str,
}

nazmulidris avatar Nov 20 '23 04:11 nazmulidris