```  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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
```
```use crate::hsl::Hsl;

#[derive(Debug)]
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}

impl Rgb {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Rgb { r, g, b }
}

/// Reduces RGB range of [0, 255] to sRGB range of [0.0, 1.0]
pub fn s_rgb(&self) -> [f64; 3] {
let (r, g, b) = (self.r as f64, self.g as f64, self.b as f64);
[r / 255.0, g / 255.0, b / 255.0]
}
}

fn hue2rgb(p: f64, q: f64, t: f64) -> f64 {
let mut t = t;
if t < 0.0 {
t += 1.0;
} else if t > 1.0 {
t -= 1.0;
}

if t < 1.0 / 6.0 {
p + (q - p) * 6.0 * t
} else if t < 1.0 / 2.0 {
q
} else if t < 2.0 / 3.0 {
p + (q - p) * (2.0 / 3.0 - t) * 6.0
} else {
p
}
}

impl From<Hsl> for Rgb {
/// Converts from the HSL to the RGB color space.
/// # Example
/// ```
/// use hsl_ish::{Hsl, Rgb};
/// let hsl = Hsl::new(120.0, 1.0, 0.5);
/// let rgb = Rgb::from(hsl);
///
/// assert_eq!((rgb.r, rgb.g, rgb.b), (0, 255, 0));
/// ```
fn from(hsl: Hsl) -> Self {
/*
h: 0 - 360,
s: 0 - 1.0,
l: 0 - 1.0,
*/
let (h, s, l) = (hsl.h / 360.0, hsl.s, hsl.l);
let ref mut r = 0.0;
let ref mut g = 0.0;
let ref mut b = 0.0;

if s == 0.0 {
*r = l;
*g = l;
*b = l;
} else {
let q = if l < 0.5 {
l * (1.0 + s)
} else {
l + s - l * s
};

let p = 2.0 * l - q;
*r = hue2rgb(p, q, h + 1.0 / 3.0);
*g = hue2rgb(p, q, h);
*b = hue2rgb(p, q, h - 1.0 / 3.0);
}

Self {
r: (*r * 255.0).round() as u8,
g: (*g * 255.0).round() as u8,
b: (*b * 255.0).round() as u8,
}
}
}

#[cfg(test)]
mod tests {
use super::*;
macro_rules! tests {
(\$(\$name:ident: \$hsl:expr, \$rgb:expr;)*) => {
\$(
#[test]
fn \$name() {
let (h, s, l) = \$hsl;
let (r, g, b) = \$rgb;
let c_hsl = Hsl::new(h, s, l);
let c_rgb = Rgb::from(c_hsl);
assert_eq!(c_rgb.r, r);
assert_eq!(c_rgb.g, g);
assert_eq!(c_rgb.b, b);
}
)*
}
}

tests! {
test0:  (0.0  , 0.0, 0.0),  (0,0,0);
test1:  (0.0  , 0.0, 1.0),  (255,255,255);
test2:  (0.0  , 1.0, 0.5),  (255,0,0);
test3:  (120.0, 1.0, 0.5),  (0,255,0);
test4:  (240.0, 1.0, 0.5),  (0,0,255);
test5:  (60.0 , 1.0, 0.5),  (255,255,0);
test6:  (180.0, 1.0, 0.5),  (0,255,255);
test7:  (300.0, 1.0, 0.5),  (255,0,255);
test8:  (0.0  , 0.0, 0.75), (191,191,191);
test9:  (0.0  , 0.0, 0.5),  (128,128,128);
test10: (0.0  , 1.0, 0.25), (128,0,0);
test11: (60.0 , 1.0, 0.25), (128,128,0); //
test12: (120.0, 1.0, 0.25), (0,128,0);
test13: (300.0, 1.0, 0.25), (128,0,128); //
test14: (180.0, 1.0, 0.25), (0,128,128); //
test15: (240.0, 1.0, 0.25), (0,0,128);
}
}
```