1 #[cfg(not(feature = "std"))]
2 use alloc::string::String;
3 
4 pub use ratio::HslRatio;
5 
6 use crate::{ColorAlpha, ColorTupleA, ColorUnitsIter, ParseError, Rgb};
7 use crate::common::{Hs, hsl_hsv_from_str, tuple_to_string, };
8 use crate::units::{Alpha, GetColorUnits, Unit, Units};
9 
10 #[cfg(test)]
11 mod tests;
12 
13 mod from;
14 mod ops;
15 mod ratio;
16 mod 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 pub struct Hsl {
27   pub(crate) units: Units,
28 }
29 
30 iter_def!(Hsl);
new_hsl_units(h: f64, s: f64, l: f64) -> Units31 pub(crate) fn new_hsl_units(h: f64, s: f64, l: f64) -> Units {
32   let ul = [Unit::new_hue(h), Unit::new_percent(s), Unit::new_percent(l), Unit::default()];
33   Units { len: 3, list: ul, alpha: Alpha::default() }
34 }
35 
36 
37 impl Hsl {
new(h: f64, s: f64, l: f64, a: Option<f64>) -> Hsl38   pub fn new(h: f64, s: f64, l: f64, a: Option<f64>) -> Hsl {
39     let mut units = new_hsl_units(h, s, l);
40     units.alpha.set_opt(a);
41     units.restrict();
42     Hsl { units }
43   }
44 
from_units(u: Units) -> Self45   pub(crate) fn from_units(u: Units) -> Self { Hsl { units: u } }
46 
to_css_string(&self) -> String47   pub fn to_css_string(&self) -> String {
48     let t: ColorTupleA = self.into();
49     tuple_to_string(&t, "hsl")
50   }
51 
hue(&self) -> f6452   pub fn hue(&self) -> f64 { self.units[0] }
saturation(&self) -> f6453   pub fn saturation(&self) -> f64 { self.units[1] }
lightness(&self) -> f6454   pub fn lightness(&self) -> f64 { self.units[2] }
55 
56   #[deprecated(since = "0.7.0", note = "Please use `hue` instead")]
get_hue(&self) -> f6457   pub fn get_hue(&self) -> f64 {
58     self.hue()
59   }
60   #[deprecated(since = "0.7.0", note = "Please use `saturation` instead")]
get_saturation(&self) -> f6461   pub fn get_saturation(&self) -> f64 {
62     self.saturation()
63   }
64   #[deprecated(since = "0.7.0", note = "Please use `lightness` instead")]
get_lightness(&self) -> f6465   pub fn get_lightness(&self) -> f64 {
66     self.lightness()
67   }
68 
set_hue(&mut self, val: f64)69   pub fn set_hue(&mut self, val: f64) { self.units.list[0].set(val); }
set_saturation(&mut self, val: f64)70   pub fn set_saturation(&mut self, val: f64) { self.units.list[1].set(val); }
set_lightness(&mut self, val: f64)71   pub fn set_lightness(&mut self, val: f64) { self.units.list[2].set(val); }
72 
73   /// Returns an iterator over three color units and the possibly alpha value.
iter(&self) -> ColorUnitsIter74   pub fn iter(&self) -> ColorUnitsIter {
75     ColorUnitsIter::from_units(&self.units)
76   }
77 
78   /// Returns an HSL representation with values converted to floar from 0.0 to 1.0
as_ratio(&self) -> HslRatio79   pub fn as_ratio(&self) -> HslRatio {
80     HslRatio::from_units(self.units.as_ratio())
81   }
82 }
83 
84 //
85 //
86 //
87 // Default
88 //
89 impl Default for Hsl {
default() -> Hsl90   fn default() -> Hsl {
91     Hsl::from_units(new_hsl_units(0.0, 0.0, 0.0))
92   }
93 }
94 
95 //
96 //
97 //
98 // AsRef<Hsl>
99 //
100 impl AsRef<Hsl> for Hsl {
as_ref(&self) -> &Hsl101   fn as_ref(&self) -> &Hsl {
102     &self
103   }
104 }
105 
106 //
107 //
108 //
109 // FromStr
110 //
111 impl core::str::FromStr for Hsl {
112   type Err = ParseError;
from_str(s: &str) -> Result<Hsl, ParseError>113   fn from_str(s: &str) -> Result<Hsl, ParseError> {
114     let (tuple, alpha) = hsl_hsv_from_str(s, Hs::Hsl)?;
115     let mut hsl = Hsl::from(&tuple);
116     if let Some(a) = alpha {
117       hsl.set_alpha(a);
118     }
119     Ok(hsl)
120   }
121 }
122 
123 
124 impl GetColorUnits for Hsl {
get_units(&self) -> &Units125   fn get_units(&self) -> &Units {
126     &self.units
127   }
get_units_mut(&mut self) -> &mut Units128   fn get_units_mut(&mut self) -> &mut Units {
129     &mut self.units
130   }
131 }
132