Skip to main content

src/main.rs

1#![deny(warnings)]
3use std::cmp::Ordering::Equal;
4use std::str::FromStr;
6use clap::Arg;
7use palette::{FromColor, Hsv, Srgb};
9const VERSION: &str = env!("CARGO_PKG_VERSION");
11#[derive(Debug)]
12struct OutputValue {
13 value: f32,
14 rgb: Srgb<u8>,
15 is_original: bool,
18fn main() {
19 let matches = clap::Command::new("brightness_adjust")
20 .version(VERSION)
21 .author("Alex Chan <alex@alexwlchan.net>")
22 .about("Show some darker/lighter variants of a given colour")
23 .arg(
24 Arg::new("COLOUR")
25 .help("colour to start with as a hex string, e.g. #d01c11")
26 .required(true)
27 .index(1),
28 )
29 .get_matches();
31 // This .unwrap() is safe because "path" is a required param
32 let base_colour = matches
33 .get_one::<String>("COLOUR")
34 .expect("`COLOUR` is required");
36 let rgb = match Srgb::from_str(base_colour) {
37 Ok(c) => c.into_format::<u8>(),
38 Err(e) => {
39 eprintln!("Unable to parse COLOUR {:?} as hex: {}", base_colour, e);
40 std::process::exit(1);
41 }
42 };
44 let hsv: Hsv = Hsv::from_color(rgb.into_format::<f32>());
46 let mut outputs = vec![OutputValue {
47 value: hsv.value,
48 rgb: rgb,
49 is_original: true,
50 }];
52 for value in (0..=100).step_by(5) {
53 let modified_hsv = Hsv::new(hsv.hue, hsv.saturation, value as f32 / 100.0);
54 outputs.push(OutputValue {
55 value: modified_hsv.value,
56 rgb: Srgb::from_color(modified_hsv).into_format::<u8>(),
57 is_original: false,
58 });
59 }
61 // https://www.reddit.com/r/rust/comments/29kia3/comment/cilrzik/
62 outputs.sort_by(|a, b| a.value.partial_cmp(&b.value).unwrap_or(Equal));
64 for op in outputs {
65 let rgb = op.rgb;
66 print!(
67 "{:3}% = \x1B[38;2;{};{};{}m▇ #{:02x}{:02x}{:02x}\x1B[0m",
68 (op.value * 100.0).round(),
69 rgb.red,
70 rgb.green,
71 rgb.blue,
72 rgb.red,
73 rgb.green,
74 rgb.blue
75 );
76 if op.is_original {
77 println!(" (original colour)");
78 } else {
79 println!("");
80 }
81 }