Skip to main content

named_colour/ext/
blue.rs

1//! Extended named colours providing shades collected in enums for the main colour
2//!
3
4use std::fmt;
5
6use rgb::Rgb;
7use strum::EnumCount;
8use tinyrand::{RandRange, StdRand};
9
10use super::ExtendedColour;
11
12/// Shades of blue
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumCount)]
14#[allow(missing_docs)]
15pub enum Blue {
16    PowderBlue,
17    CadetBlue,
18    SteelBlue,
19    CornflowerBlue,
20    DeepSkyBlue,
21    DodgerBlue,
22    LightBlue,
23    SkyBlue,
24    LightSkyBlue,
25    MidnightBlue,
26    Navy,
27    DarkBlue,
28    MediumBlue,
29    Blue,
30    RoyalBlue,
31    Azure,
32    LightSteelBlue,
33}
34
35impl fmt::Display for Blue {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::PowderBlue => write!(f, "#B0E0E6"),
39            Self::CadetBlue => write!(f, "#5F9EA0"),
40            Self::SteelBlue => write!(f, "#4682B4"),
41            Self::CornflowerBlue => write!(f, "#6495ED"),
42            Self::DeepSkyBlue => write!(f, "#00BFFF"),
43            Self::DodgerBlue => write!(f, "#1E90FF"),
44            Self::LightBlue => write!(f, "#ADD8E6"),
45            Self::SkyBlue => write!(f, "#87CEEB"),
46            Self::LightSkyBlue => write!(f, "#87CEFA"),
47            Self::LightSteelBlue => write!(f, "#B0C4DE"),
48            Self::MidnightBlue => write!(f, "#191970"),
49            Self::Navy => write!(f, "#000080"),
50            Self::DarkBlue => write!(f, "#00008B"),
51            Self::MediumBlue => write!(f, "#0000CD"),
52            Self::Blue => write!(f, "#0000FF"),
53            Self::RoyalBlue => write!(f, "#4169E1"),
54            Self::Azure => write!(f, "#F0FFFF"),
55        }
56    }
57}
58
59impl_colour_methods!(Blue);
60
61impl Blue {
62    /// Parse a colour from string
63    ///
64    /// ## Example
65    ///
66    ///```
67    /// # use named_colour::ext::Blue;
68    /// # use named_colour::Prefix;
69    ///    let colour = Blue::Azure;
70    ///
71    ///     assert_eq!(Blue::Azure, Blue::parse("#F0FFFF").unwrap());
72    ///
73    ///```
74    pub fn parse(name: &str) -> Option<Self> {
75        match name.to_lowercase().as_str() {
76            "#b0e0e6" | "b0e0e6" | "powderblue" => Some(Self::PowderBlue),
77            "#5f9ea0" | "5f9ea0" | "cadetblue" => Some(Self::CadetBlue),
78            "#4682b4" | "4682b4" | "steelblue" => Some(Self::SteelBlue),
79            "#6495ed" | "6495ed" | "cornflowerblue" => Some(Self::CornflowerBlue),
80            "#00bfff" | "00bfff" | "deepskyblue" => Some(Self::DeepSkyBlue),
81            "#1e90ff" | "1e90ff" | "dodgerblue" => Some(Self::DodgerBlue),
82            "#add8e6" | "add8e6" | "lightblue" => Some(Self::LightBlue),
83            "#87ceeb" | "87ceeb" | "skyblue" => Some(Self::SkyBlue),
84            "#b0c4de" | "b0c4de" | "lightsteelblue" => Some(Self::LightSteelBlue),
85            "#87cefa" | "87cefa" | "lightskyblue" => Some(Self::LightSkyBlue),
86            "#191970" | "191970" | "midnightblue" => Some(Self::MidnightBlue),
87            "#000080" | "000080" | "navy" => Some(Self::Navy),
88            "#00008b" | "00008b" | "darkblue" => Some(Self::DarkBlue),
89            "#0000cd" | "0000cd" | "mediumblue" => Some(Self::MediumBlue),
90            "#0000ff" | "0000ff" | "blue" => Some(Self::Blue),
91            "#4169e1" | "4169e1" | "royalblue" => Some(Self::RoyalBlue),
92            "#f0ffff" | "f0ffff" | "azure" => Some(Self::Azure),
93            _ => None,
94        }
95    }
96
97    /// Generate a random colour
98    ///     
99    /// ## Example
100    ///
101    ///```
102    /// # use named_colour::ext::Blue;
103    /// # fn main() {
104    ///    let colour = Blue::random();
105    ///
106    /// # }
107    /// ```
108    pub fn random() -> Self {
109        let mut rand = StdRand::default();
110
111        match rand.next_range(0..Self::COUNT) {
112            0 => Self::PowderBlue,
113            1 => Self::CadetBlue,
114            2 => Self::SteelBlue,
115            3 => Self::CornflowerBlue,
116            4 => Self::DeepSkyBlue,
117            5 => Self::DodgerBlue,
118            6 => Self::LightBlue,
119            7 => Self::SkyBlue,
120            8 => Self::LightSkyBlue,
121            9 => Self::LightSteelBlue,
122            10 => Self::MidnightBlue,
123            11 => Self::Navy,
124            12 => Self::DarkBlue,
125            13 => Self::MediumBlue,
126            14 => Self::Blue,
127            15 => Self::RoyalBlue,
128            16 => Self::Azure,
129            _ => Self::Blue,
130        }
131    }
132}
133
134impl ExtendedColour for Blue {}
135
136#[cfg(test)]
137mod tests {
138    use std::str::FromStr;
139
140    use crate::Prefix;
141
142    use super::*;
143    use rstest::rstest;
144
145    #[rstest]
146    #[case(Blue::PowderBlue, "rgb(176,224,230)")]
147    #[case(Blue::CadetBlue, "rgb(95,158,160)")]
148    #[case(Blue::SteelBlue, "rgb(70,130,180)")]
149    #[case(Blue::CornflowerBlue, "rgb(100,149,237)")]
150    #[case(Blue::DeepSkyBlue, "rgb(0,191,255)")]
151    #[case(Blue::DodgerBlue, "rgb(30,144,255)")]
152    #[case(Blue::LightBlue, "rgb(173,216,230)")]
153    #[case(Blue::SkyBlue, "rgb(135,206,235)")]
154    #[case(Blue::LightSteelBlue, "rgb(176,196,222)")]
155    #[case(Blue::LightSkyBlue, "rgb(135,206,250)")]
156    #[case(Blue::MidnightBlue, "rgb(25,25,112)")]
157    #[case(Blue::Navy, "rgb(0,0,128)")]
158    #[case(Blue::DarkBlue, "rgb(0,0,139)")]
159    #[case(Blue::MediumBlue, "rgb(0,0,205)")]
160    #[case(Blue::Blue, "rgb(0,0,255)")]
161    #[case(Blue::RoyalBlue, "rgb(65,105,225)")]
162    #[case(Blue::Azure, "rgb(240,255,255)")]
163
164    fn test_rgb_string(#[case] colour: Blue, #[case] expected: String) {
165        let rgb_colour = colour.to_rgb();
166        let string = rgb_colour.to_string();
167
168        assert_eq!(expected, string);
169    }
170
171    #[rstest]
172    #[case(Blue::PowderBlue, "B0E0E6")]
173    #[case(Blue::CadetBlue, "5F9EA0")]
174    #[case(Blue::SteelBlue, "4682B4")]
175    #[case(Blue::CornflowerBlue, "6495ED")]
176    #[case(Blue::DeepSkyBlue, "00BFFF")]
177    #[case(Blue::DodgerBlue, "1E90FF")]
178    #[case(Blue::LightBlue, "ADD8E6")]
179    #[case(Blue::SkyBlue, "87CEEB")]
180    #[case(Blue::LightSteelBlue, "B0C4DE")]
181    #[case(Blue::LightSkyBlue, "87CEFA")]
182    #[case(Blue::MidnightBlue, "191970")]
183    #[case(Blue::Navy, "000080")]
184    #[case(Blue::DarkBlue, "00008B")]
185    #[case(Blue::MediumBlue, "0000CD")]
186    #[case(Blue::Blue, "0000FF")]
187    #[case(Blue::RoyalBlue, "4169E1")]
188    #[case(Blue::Azure, "F0FFFF")]
189
190    fn test_hex_triplet_string(
191        #[case] colour: Blue,
192        #[values(Prefix::None, Prefix::Hash)] prefix: Prefix,
193        #[case] expected: String,
194    ) {
195        let prefix_string = match prefix {
196            Prefix::None => "".to_string(),
197            Prefix::Hash => "#".to_string(),
198        };
199
200        let expected = format!("{prefix_string}{expected}");
201
202        let hex_colour = colour.to_hex_triplet(prefix);
203
204        assert_eq!(expected, hex_colour);
205    }
206
207    #[rstest]
208    #[case("#b0e0e6", Blue::PowderBlue)]
209    #[case("b0e0e6", Blue::PowderBlue)]
210    #[case("powderblue", Blue::PowderBlue)]
211    #[case("#5f9ea0", Blue::CadetBlue)]
212    #[case("5f9ea0", Blue::CadetBlue)]
213    #[case("cadetblue", Blue::CadetBlue)]
214    #[case("#4682b4", Blue::SteelBlue)]
215    #[case("4682b4", Blue::SteelBlue)]
216    #[case("steelblue", Blue::SteelBlue)]
217    #[case("#6495ed", Blue::CornflowerBlue)]
218    #[case("6495ed", Blue::CornflowerBlue)]
219    #[case("cornflowerblue", Blue::CornflowerBlue)]
220    #[case("#00bfff", Blue::DeepSkyBlue)]
221    #[case("00bfff", Blue::DeepSkyBlue)]
222    #[case("deepskyblue", Blue::DeepSkyBlue)]
223    #[case("#1e90ff", Blue::DodgerBlue)]
224    #[case("1e90ff", Blue::DodgerBlue)]
225    #[case("dodgerblue", Blue::DodgerBlue)]
226    #[case("#add8e6", Blue::LightBlue)]
227    #[case("add8e6", Blue::LightBlue)]
228    #[case("lightblue", Blue::LightBlue)]
229    #[case("#87ceeb", Blue::SkyBlue)]
230    #[case("87ceeb", Blue::SkyBlue)]
231    #[case("skyblue", Blue::SkyBlue)]
232    #[case("#b0c4de", Blue::LightSteelBlue)]
233    #[case("b0c4de", Blue::LightSteelBlue)]
234    #[case("lightsteelblue", Blue::LightSteelBlue)]
235    #[case("#87cefa", Blue::LightSkyBlue)]
236    #[case("87cefa", Blue::LightSkyBlue)]
237    #[case("lightskyblue", Blue::LightSkyBlue)]
238    #[case("#191970", Blue::MidnightBlue)]
239    #[case("191970", Blue::MidnightBlue)]
240    #[case("midnightblue", Blue::MidnightBlue)]
241    #[case("#000080", Blue::Navy)]
242    #[case("000080", Blue::Navy)]
243    #[case("navy", Blue::Navy)]
244    #[case("#00008b", Blue::DarkBlue)]
245    #[case("00008b", Blue::DarkBlue)]
246    #[case("darkblue", Blue::DarkBlue)]
247    #[case("#0000cd", Blue::MediumBlue)]
248    #[case("0000cd", Blue::MediumBlue)]
249    #[case("mediumblue", Blue::MediumBlue)]
250    #[case("#0000ff", Blue::Blue)]
251    #[case("0000ff", Blue::Blue)]
252    #[case("blue", Blue::Blue)]
253    #[case("#4169e1", Blue::RoyalBlue)]
254    #[case("4169e1", Blue::RoyalBlue)]
255    #[case("royalblue", Blue::RoyalBlue)]
256    #[case("#f0ffff", Blue::Azure)]
257    #[case("f0ffff", Blue::Azure)]
258    #[case("azure", Blue::Azure)]
259    fn test_from_str(#[case] input: &str, #[case] expected: Blue) {
260        assert_eq!(expected, Blue::from_str(input).unwrap())
261    }
262
263    #[rstest]
264    #[case("#b0e0e6", Some(Blue::PowderBlue))]
265    #[case("b0e0e6", Some(Blue::PowderBlue))]
266    #[case("powderblue", Some(Blue::PowderBlue))]
267    #[case("#5f9ea0", Some(Blue::CadetBlue))]
268    #[case("5f9ea0", Some(Blue::CadetBlue))]
269    #[case("cadetblue", Some(Blue::CadetBlue))]
270    #[case("#4682b4", Some(Blue::SteelBlue))]
271    #[case("4682b4", Some(Blue::SteelBlue))]
272    #[case("steelblue", Some(Blue::SteelBlue))]
273    #[case("#6495ed", Some(Blue::CornflowerBlue))]
274    #[case("6495ed", Some(Blue::CornflowerBlue))]
275    #[case("cornflowerblue", Some(Blue::CornflowerBlue))]
276    #[case("#00bfff", Some(Blue::DeepSkyBlue))]
277    #[case("00bfff", Some(Blue::DeepSkyBlue))]
278    #[case("deepskyblue", Some(Blue::DeepSkyBlue))]
279    #[case("#1e90ff", Some(Blue::DodgerBlue))]
280    #[case("1e90ff", Some(Blue::DodgerBlue))]
281    #[case("dodgerblue", Some(Blue::DodgerBlue))]
282    #[case("#add8e6", Some(Blue::LightBlue))]
283    #[case("add8e6", Some(Blue::LightBlue))]
284    #[case("lightblue", Some(Blue::LightBlue))]
285    #[case("#87ceeb", Some(Blue::SkyBlue))]
286    #[case("87ceeb", Some(Blue::SkyBlue))]
287    #[case("skyblue", Some(Blue::SkyBlue))]
288    #[case("#b0c4de", Some(Blue::LightSteelBlue))]
289    #[case("b0c4de", Some(Blue::LightSteelBlue))]
290    #[case("lightsteelblue", Some(Blue::LightSteelBlue))]
291    #[case("#87cefa", Some(Blue::LightSkyBlue))]
292    #[case("87cefa", Some(Blue::LightSkyBlue))]
293    #[case("lightskyblue", Some(Blue::LightSkyBlue))]
294    #[case("#191970", Some(Blue::MidnightBlue))]
295    #[case("191970", Some(Blue::MidnightBlue))]
296    #[case("midnightblue", Some(Blue::MidnightBlue))]
297    #[case("#000080", Some(Blue::Navy))]
298    #[case("000080", Some(Blue::Navy))]
299    #[case("navy", Some(Blue::Navy))]
300    #[case("#00008b", Some(Blue::DarkBlue))]
301    #[case("00008b", Some(Blue::DarkBlue))]
302    #[case("darkblue", Some(Blue::DarkBlue))]
303    #[case("#0000cd", Some(Blue::MediumBlue))]
304    #[case("0000cd", Some(Blue::MediumBlue))]
305    #[case("mediumblue", Some(Blue::MediumBlue))]
306    #[case("#0000ff", Some(Blue::Blue))]
307    #[case("0000ff", Some(Blue::Blue))]
308    #[case("blue", Some(Blue::Blue))]
309    #[case("#4169e1", Some(Blue::RoyalBlue))]
310    #[case("4169e1", Some(Blue::RoyalBlue))]
311    #[case("royalblue", Some(Blue::RoyalBlue))]
312    #[case("#f0ffff", Some(Blue::Azure))]
313    #[case("f0ffff", Some(Blue::Azure))]
314    #[case("azure", Some(Blue::Azure))]
315    #[case("012345", None)]
316    fn test_name_colour(#[case] input: &str, #[case] expected: Option<Blue>) {
317        assert_eq!(expected, Blue::name_colour(input))
318    }
319}