1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Rgb {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b }
}
pub fn to_ansi(self) -> AnsiColor {
AnsiColor {
code: ansi_colours::ansi256_from_rgb((self.r, self.g, self.b)),
}
}
#[allow(clippy::float_cmp)]
pub fn to_hsl(self) -> Hsl {
let (r, g, b) = (self.rp(), self.gp(), self.bp());
let min = r.min(g).min(b);
let max = r.max(g).max(b);
let l = 0.5 * (max + min);
if min == max {
return Hsl::new(0.0, 0.0, l);
}
let h = if max == r {
60.0 * (g - b) / (max - min)
} else if max == g {
60.0 * (b - r) / (max - min) + 120.0
} else if max == b {
60.0 * (r - g) / (max - min) + 240.0
} else {
0.0
};
let h = (h + 360.0) % 360.0;
let s = if 0.0 < l && l <= 0.5 {
(max - min) / (2.0 * l)
} else {
(max - min) / (2.0 - 2.0 * l)
};
Hsl { h, s, l }
}
pub fn rp(self) -> f32 {
self.r as f32 / 256f32
}
pub fn gp(self) -> f32 {
self.g as f32 / 256f32
}
pub fn bp(self) -> f32 {
self.b as f32 / 256f32
}
pub fn luma(self) -> f32 {
0.2627 * self.rp() + 0.6780 * self.gp() + 0.0593 * self.bp()
}
}
impl From<(f32, f32, f32)> for Rgb {
fn from(c: (f32, f32, f32)) -> Self {
debug_assert!(c.0<=1.0);
debug_assert!(c.1<=1.0);
debug_assert!(c.2<=1.0);
Rgb::new(
(c.0 * 255.0).round() as u8,
(c.1 * 255.0).round() as u8,
(c.2 * 255.0).round() as u8,
)
}
}