colors_transform/colors/
hsl.rs1use super::Rgb;
2use crate::converters::{as_rounded_hsl_tuple, hsl_to_rgb, invert_hue};
3use crate::error::ParseError;
4use crate::normalize::{normalize_hsl, normalize_hue, normalize_percent, normalize_ratio};
5use crate::{from_str, AlphaColor, Color, ColorTuple, ColorTupleA, RgbUnit};
6
7#[derive(Clone, Copy, Debug, PartialEq)]
8pub struct Hsl {
9 h: f32,
10 s: f32,
11 l: f32,
12 a: Option<f32>,
13}
14
15impl Hsl {
16 pub fn from(h: f32, s: f32, l: f32) -> Hsl {
17 Hsl::from_tuple(&(h, s, l))
18 }
19
20 pub fn grayscale(&self) -> Hsl {
21 Hsl { h: 0.0, s: 0.0, l: self.l, a: self.a }
22 }
23}
24
25impl std::str::FromStr for Hsl {
26 type Err = ParseError;
27
28 fn from_str(s: &str) -> Result<Hsl, ParseError> {
29 match from_str::hsl(s) {
30 Ok(hsl_tuple) => Ok(Hsl::from_tuple(&hsl_tuple)),
31 Err(err) => Err(err),
32 }
33 }
34}
35
36impl Color for Hsl {
37 type Tuple = ColorTuple;
38 type TupleA = ColorTupleA;
39
40 fn new() -> Hsl {
41 Hsl { h: 0.0, s: 0.0, l: 0.0, a: None }
42 }
43
44 fn get_hue(&self) -> f32 {
45 self.h
46 }
47 fn get_saturation(&self) -> f32 {
48 self.s
49 }
50 fn get_lightness(&self) -> f32 {
51 self.l
52 }
53 fn set_hue(&self, val: f32) -> Hsl {
54 Hsl { h: normalize_hue(val), s: self.s, l: self.l, a: self.a }
55 }
56 fn set_saturation(&self, val: f32) -> Hsl {
57 Hsl { h: self.h, s: normalize_percent(val), l: self.l, a: self.a }
58 }
59 fn set_lightness(&self, val: f32) -> Hsl {
60 Hsl { h: self.h, s: self.s, l: normalize_percent(val), a: self.a }
61 }
62
63 fn get_red(&self) -> f32 {
64 self.to_rgb().get_red()
65 }
66 fn get_green(&self) -> f32 {
67 self.to_rgb().get_green()
68 }
69 fn get_blue(&self) -> f32 {
70 self.to_rgb().get_blue()
71 }
72 fn set_red(&self, val: f32) -> Hsl {
73 self.to_rgb().set_red(val).to_hsl()
74 }
75 fn set_green(&self, val: f32) -> Hsl {
76 self.to_rgb().set_green(val).to_hsl()
77 }
78 fn set_blue(&self, val: f32) -> Hsl {
79 self.to_rgb().set_blue(val).to_hsl()
80 }
81
82 fn to_rgb(&self) -> Rgb {
83 Rgb::from_tuple(&hsl_to_rgb(&self.as_tuple()))
84 }
85 fn to_hsl(&self) -> Hsl {
86 *self
87 }
88 fn to_css_string(&self) -> String {
89 let (h, s, l) = as_rounded_hsl_tuple(&self.as_tuple());
90 format!("hsl({},{}%,{}%)", h, s, l)
91 }
92 fn from_tuple(t: &ColorTuple) -> Hsl {
93 let (h, s, l) = normalize_hsl(&t);
94 Hsl { h, s, l, a: None }
95 }
96 fn from_tuple_with_alpha(t: &ColorTupleA) -> Hsl {
97 let (h, s, l, a) = *t;
98 let (h, s, l) = normalize_hsl(&(h, s, l));
99 Hsl { h, s, l, a: Some(normalize_ratio(a)) }
100 }
101 fn as_tuple(&self) -> ColorTuple {
102 (self.h, self.s, self.l)
103 }
104 fn lighten(&self, val: f32) -> Hsl {
105 self.set_lightness(self.l + val)
106 }
107 fn saturate(&self, val: f32) -> Hsl {
108 self.set_saturation(self.s + val)
109 }
110 fn adjust_hue(&self, hue: f32) -> Hsl {
111 self.set_hue(self.h + hue)
112 }
113 fn adjust_color(&self, name: RgbUnit, val: f32) -> Hsl {
114 self.to_rgb().adjust_color(name, val).to_hsl()
115 }
116
117 fn invert(&self) -> Hsl {
118 Hsl { h: invert_hue(self.h), s: self.s, l: self.l, a: self.a }
119 }
120}
121
122impl AlphaColor for Hsl {
123 fn get_alpha(&self) -> f32 {
124 self.a.unwrap_or(1.0)
125 }
126 fn set_alpha(&self, a: f32) -> Hsl {
127 Hsl { h: self.h, s: self.s, l: self.l, a: Some(normalize_ratio(a)) }
128 }
129 fn opacify(&self, a: f32) -> Hsl {
130 self.set_alpha(self.get_alpha() + a)
131 }
132}