colors_transform/colors/
hsl.rs

1use 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}