colorsys/hsl/
mod.rs

1#[cfg(not(feature = "std"))]
2use alloc::string::String;
3
4pub use ratio::HslRatio;
5
6use crate::{ColorAlpha, ColorTupleA, ColorUnitsIter, ParseError, Rgb};
7use crate::common::{Hs, hsl_hsv_from_str, tuple_to_string};
8use crate::units::{Alpha, GetColorUnits, Unit, Units};
9
10#[cfg(test)]
11mod tests;
12
13mod from;
14mod ops;
15mod ratio;
16mod transform;
17
18/// The HSL or HSI (hue, saturation, lightness (intensity)) color model
19///
20/// Ranges:
21/// * hue: 0.0 - 360.0
22/// * saturation: 0.0 - 100.0
23/// * saturation: 0.0 - 100.0
24/// * alpha: 0.0 - 1.0
25#[derive(Debug, PartialEq, Clone)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub struct Hsl {
28  pub(crate) units: Units,
29}
30
31iter_def!(Hsl);
32pub(crate) fn new_hsl_units(h: f64, s: f64, l: f64) -> Units {
33  let ul = [Unit::new_hue(h), Unit::new_percent(s), Unit::new_percent(l), Unit::default()];
34  Units { len: 3, list: ul, alpha: Alpha::default() }
35}
36
37
38impl Hsl {
39  pub fn new(h: f64, s: f64, l: f64, a: Option<f64>) -> Hsl {
40    let mut units = new_hsl_units(h, s, l);
41    units.alpha.set_opt(a);
42    units.restrict();
43    Hsl { units }
44  }
45
46  pub(crate) fn from_units(u: Units) -> Self { Hsl { units: u } }
47
48  pub fn to_css_string(&self) -> String {
49    let t: ColorTupleA = self.into();
50    tuple_to_string(&t, "hsl")
51  }
52
53  pub fn hue(&self) -> f64 { self.units[0] }
54  pub fn saturation(&self) -> f64 { self.units[1] }
55  pub fn lightness(&self) -> f64 { self.units[2] }
56
57  #[deprecated(since = "0.7.0", note = "Please use `hue` instead")]
58  pub fn get_hue(&self) -> f64 {
59    self.hue()
60  }
61  #[deprecated(since = "0.7.0", note = "Please use `saturation` instead")]
62  pub fn get_saturation(&self) -> f64 {
63    self.saturation()
64  }
65  #[deprecated(since = "0.7.0", note = "Please use `lightness` instead")]
66  pub fn get_lightness(&self) -> f64 {
67    self.lightness()
68  }
69
70  pub fn set_hue(&mut self, val: f64) { self.units.list[0].set(val); }
71  pub fn set_saturation(&mut self, val: f64) { self.units.list[1].set(val); }
72  pub fn set_lightness(&mut self, val: f64) { self.units.list[2].set(val); }
73
74  /// Returns an iterator over three color units and the possibly alpha value.
75  pub fn iter(&self) -> ColorUnitsIter {
76    ColorUnitsIter::from_units(&self.units)
77  }
78
79  /// Returns an HSL representation with values converted to floar from 0.0 to 1.0
80  pub fn as_ratio(&self) -> HslRatio {
81    HslRatio::from_units(self.units.as_ratio())
82  }
83}
84
85//
86//
87//
88// Default
89//
90impl Default for Hsl {
91  fn default() -> Hsl {
92    Hsl::from_units(new_hsl_units(0.0, 0.0, 0.0))
93  }
94}
95
96//
97//
98//
99// AsRef<Hsl>
100//
101impl AsRef<Hsl> for Hsl {
102  fn as_ref(&self) -> &Hsl {
103    self
104  }
105}
106
107//
108//
109//
110// FromStr
111//
112impl core::str::FromStr for Hsl {
113  type Err = ParseError;
114  fn from_str(s: &str) -> Result<Hsl, ParseError> {
115    let (tuple, alpha) = hsl_hsv_from_str(s, Hs::Hsl)?;
116    let mut hsl = Hsl::from(&tuple);
117    if let Some(a) = alpha {
118      hsl.set_alpha(a);
119    }
120    Ok(hsl)
121  }
122}
123
124
125impl GetColorUnits for Hsl {
126  fn get_units(&self) -> &Units {
127    &self.units
128  }
129  fn get_units_mut(&mut self) -> &mut Units {
130    &mut self.units
131  }
132}