Skip to main content

named_colour/ext/
purple.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 purple
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumCount)]
14#[allow(missing_docs)]
15pub enum Purple {
16    Indigo,
17    Purple,
18    DarkMagenta,
19    DarkViolet,
20    DarkSlateBlue,
21    BlueViolet,
22    DarkOrchid,
23    Fuchsia,
24    Magenta,
25    SlateBlue,
26    MediumSlateBlue,
27    MediumOrchid,
28    MediumPurple,
29    Orchid,
30    Violet,
31    Plum,
32    Thistle,
33    Lavender,
34    Pink,
35    MediumVioletRed,
36    PaleVioletRed,
37    DeepPink,
38    HotPink,
39    LightPink,
40}
41
42impl fmt::Display for Purple {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        match self {
45            Self::Indigo => write!(f, "#4B0082"),
46            Self::Purple => write!(f, "#800080"),
47            Self::DarkMagenta => write!(f, "#8B008B"),
48            Self::DarkViolet => write!(f, "#9400D3"),
49            Self::DarkSlateBlue => write!(f, "#483D8B"),
50            Self::BlueViolet => write!(f, "#8A2BE2"),
51            Self::DarkOrchid => write!(f, "#9932CC"),
52            Self::Fuchsia => write!(f, "#FF00FF"),
53            Self::Magenta => write!(f, "#FF00FF"),
54            Self::SlateBlue => write!(f, "#6A5ACD"),
55            Self::MediumSlateBlue => write!(f, "#7B68EE"),
56            Self::MediumOrchid => write!(f, "#BA55D3"),
57            Self::MediumPurple => write!(f, "#9370DB"),
58            Self::Orchid => write!(f, "#DA70D6"),
59            Self::Violet => write!(f, "#EE82EE"),
60            Self::Plum => write!(f, "#DDA0DD"),
61            Self::Thistle => write!(f, "#D8BFD8"),
62            Self::Lavender => write!(f, "#E6E6FA"),
63            Self::Pink => write!(f, "#FFC0CB"),
64            Self::MediumVioletRed => write!(f, "#C71585"),
65            Self::PaleVioletRed => write!(f, "#DB7093"),
66            Self::DeepPink => write!(f, "#FF1493"),
67            Self::HotPink => write!(f, "#FF69B4"),
68            Self::LightPink => write!(f, "#FFB6C1"),
69        }
70    }
71}
72
73impl_colour_methods!(Purple);
74
75impl Purple {
76    /// Parse a colour from string
77    ///
78    /// ## Example
79    ///
80    /// ```
81    /// # use named_colour::ext::Purple;
82    /// # fn main() {
83    ///    let colour = Purple::Purple;
84    ///    assert_eq!(colour, Purple::parse("purple").unwrap());
85    ///    assert_eq!(colour, Purple::parse("#800080").unwrap());
86    ///    assert_eq!(colour, Purple::parse("#800080").unwrap());
87    ///
88    /// # }
89    /// ```
90    pub fn parse(name: &str) -> Option<Self> {
91        match name.to_lowercase().as_str() {
92            "#4b0082" | "4b0082" | "indigo" => Some(Self::Indigo),
93            "#800080" | "800080" | "purple" => Some(Self::Purple),
94            "#8b008b" | "8b008b" | "darkmagenta" => Some(Self::DarkMagenta),
95            "#9400d3" | "9400d3" | "darkviolet" => Some(Self::DarkViolet),
96            "#483d8b" | "483d8b" | "darkslateblue" => Some(Self::DarkSlateBlue),
97            "#8a2be2" | "8a2be2" | "blueviolet" => Some(Self::BlueViolet),
98            "#9932cc" | "9932cc" | "darkorchid" => Some(Self::DarkOrchid),
99            "#a020f0" | "a020f0" | "fuchsia" => Some(Self::Fuchsia),
100            "#ff00ff" | "ff00ff" | "magenta" => Some(Self::Magenta),
101            "#6a5acd" | "6a5acd" | "slateblue" => Some(Self::SlateBlue),
102            "#7b68ee" | "7b68ee" | "mediumslateblue" => Some(Self::MediumSlateBlue),
103            "#ba55d3" | "ba55d3" | "mediumorchid" => Some(Self::MediumOrchid),
104            "#9370db" | "9370db" | "mediumpurple" => Some(Self::MediumPurple),
105            "#da70d6" | "da70d6" | "orchid" => Some(Self::Orchid),
106            "#ee82ee" | "ee82ee" | "violet" => Some(Self::Violet),
107            "#dda0dd" | "dda0dd" | "plum" => Some(Self::Plum),
108            "#d8bfd8" | "d8bfd8" | "thistle" => Some(Self::Thistle),
109            "#e6e6fa" | "e6e6fa" | "lavender" => Some(Self::Lavender),
110            "#ffc0cb" | "ffc0cb" | "pink" => Some(Self::Pink),
111            "#c71585" | "c71585" | "mediumvioletred" => Some(Self::MediumVioletRed),
112            "#db7093" | "db7093" | "palevioletred" => Some(Self::PaleVioletRed),
113            "#ff1493" | "ff1493" | "deeppink" => Some(Self::DeepPink),
114            "#ff69b4" | "ff69b4" | "hotpink" => Some(Self::HotPink),
115            "#ffb6c1" | "ffb6c1" | "lightpink" => Some(Self::LightPink),
116            _ => None,
117        }
118    }
119
120    /// Generate a random colour
121    ///     
122    /// ## Example
123    ///
124    ///```
125    /// # use named_colour::ext::Purple;
126    /// # fn main() {
127    ///    let colour = Purple::random();
128    ///
129    /// # }
130    /// ```
131    pub fn random() -> Self {
132        let mut rand = StdRand::default();
133
134        match rand.next_range(0..Self::COUNT) {
135            0 => Self::Indigo,
136            1 => Self::Purple,
137            2 => Self::DarkMagenta,
138            3 => Self::DarkViolet,
139            4 => Self::DarkSlateBlue,
140            5 => Self::BlueViolet,
141            6 => Self::DarkOrchid,
142            7 => Self::Fuchsia,
143            8 => Self::Magenta,
144            9 => Self::SlateBlue,
145            10 => Self::MediumSlateBlue,
146            11 => Self::MediumOrchid,
147            12 => Self::MediumPurple,
148            13 => Self::Orchid,
149            14 => Self::Violet,
150            15 => Self::Plum,
151            16 => Self::Thistle,
152            17 => Self::Lavender,
153            18 => Self::Pink,
154            19 => Self::MediumVioletRed,
155            20 => Self::PaleVioletRed,
156            21 => Self::DeepPink,
157            22 => Self::HotPink,
158            23 => Self::LightPink,
159            _ => Self::Purple,
160        }
161    }
162}
163
164impl ExtendedColour for Purple {}
165
166#[cfg(test)]
167mod tests {
168    use std::str::FromStr;
169
170    use crate::Prefix;
171
172    use super::*;
173    use rstest::rstest;
174
175    #[rstest]
176    #[case(Purple::Purple, "rgb(128,0,128)")]
177    #[case(Purple::Thistle, "rgb(216,191,216)")]
178    #[case(Purple::Plum, "rgb(221,160,221)")]
179    #[case(Purple::Violet, "rgb(238,130,238)")]
180    #[case(Purple::Magenta, "rgb(255,0,255)")]
181    #[case(Purple::Fuchsia, "rgb(255,0,255)")]
182    #[case(Purple::Orchid, "rgb(218,112,214)")]
183    #[case(Purple::MediumVioletRed, "rgb(199,21,133)")]
184    #[case(Purple::PaleVioletRed, "rgb(219,112,147)")]
185    #[case(Purple::DeepPink, "rgb(255,20,147)")]
186    #[case(Purple::HotPink, "rgb(255,105,180)")]
187    #[case(Purple::LightPink, "rgb(255,182,193)")]
188    #[case(Purple::Pink, "rgb(255,192,203)")]
189    fn test_rgb_string(#[case] colour: Purple, #[case] expected: String) {
190        let rgb_colour = colour.to_rgb();
191        let string = rgb_colour.to_string();
192
193        assert_eq!(expected, string);
194    }
195
196    #[rstest]
197    #[case(Purple::Purple, "800080")]
198    #[case(Purple::Thistle, "D8BFD8")]
199    #[case(Purple::Plum, "DDA0DD")]
200    #[case(Purple::Violet, "EE82EE")]
201    #[case(Purple::Magenta, "FF00FF")]
202    #[case(Purple::Fuchsia, "FF00FF")]
203    #[case(Purple::Orchid, "DA70D6")]
204    #[case(Purple::MediumVioletRed, "C71585")]
205    #[case(Purple::PaleVioletRed, "DB7093")]
206    #[case(Purple::DeepPink, "FF1493")]
207    #[case(Purple::HotPink, "FF69B4")]
208    #[case(Purple::LightPink, "FFB6C1")]
209    #[case(Purple::Pink, "FFC0CB")]
210    fn test_hex_triplet_string(
211        #[case] colour: Purple,
212        #[values(Prefix::None, Prefix::Hash)] prefix: Prefix,
213        #[case] expected: String,
214    ) {
215        let prefix_string = match prefix {
216            Prefix::None => "".to_string(),
217            Prefix::Hash => "#".to_string(),
218        };
219
220        let expected = format!("{prefix_string}{expected}");
221
222        let hex_colour = colour.to_hex_triplet(prefix);
223
224        assert_eq!(expected, hex_colour);
225    }
226
227    #[rstest]
228    #[case("#4b0082", Purple::Indigo)]
229    #[case("4b0082", Purple::Indigo)]
230    #[case("indigo", Purple::Indigo)]
231    #[case("#800080", Purple::Purple)]
232    #[case("800080", Purple::Purple)]
233    #[case("purple", Purple::Purple)]
234    #[case("#8b008b", Purple::DarkMagenta)]
235    #[case("8b008b", Purple::DarkMagenta)]
236    #[case("darkmagenta", Purple::DarkMagenta)]
237    #[case("#9400d3", Purple::DarkViolet)]
238    #[case("9400d3", Purple::DarkViolet)]
239    #[case("darkviolet", Purple::DarkViolet)]
240    #[case("#483d8b", Purple::DarkSlateBlue)]
241    #[case("483d8b", Purple::DarkSlateBlue)]
242    #[case("darkslateblue", Purple::DarkSlateBlue)]
243    #[case("#8a2be2", Purple::BlueViolet)]
244    #[case("8a2be2", Purple::BlueViolet)]
245    #[case("blueviolet", Purple::BlueViolet)]
246    #[case("#9932cc", Purple::DarkOrchid)]
247    #[case("9932cc", Purple::DarkOrchid)]
248    #[case("darkorchid", Purple::DarkOrchid)]
249    #[case("#a020f0", Purple::Fuchsia)]
250    #[case("a020f0", Purple::Fuchsia)]
251    #[case("fuchsia", Purple::Fuchsia)]
252    #[case("#ff00ff", Purple::Magenta)]
253    #[case("ff00ff", Purple::Magenta)]
254    #[case("magenta", Purple::Magenta)]
255    #[case("#6a5acd", Purple::SlateBlue)]
256    #[case("6a5acd", Purple::SlateBlue)]
257    #[case("slateblue", Purple::SlateBlue)]
258    #[case("#7b68ee", Purple::MediumSlateBlue)]
259    #[case("7b68ee", Purple::MediumSlateBlue)]
260    #[case("mediumslateblue", Purple::MediumSlateBlue)]
261    #[case("#ba55d3", Purple::MediumOrchid)]
262    #[case("ba55d3", Purple::MediumOrchid)]
263    #[case("mediumorchid", Purple::MediumOrchid)]
264    #[case("#9370db", Purple::MediumPurple)]
265    #[case("9370db", Purple::MediumPurple)]
266    #[case("mediumpurple", Purple::MediumPurple)]
267    #[case("#da70d6", Purple::Orchid)]
268    #[case("da70d6", Purple::Orchid)]
269    #[case("orchid", Purple::Orchid)]
270    #[case("#ee82ee", Purple::Violet)]
271    #[case("ee82ee", Purple::Violet)]
272    #[case("violet", Purple::Violet)]
273    #[case("#dda0dd", Purple::Plum)]
274    #[case("dda0dd", Purple::Plum)]
275    #[case("plum", Purple::Plum)]
276    #[case("#d8bfd8", Purple::Thistle)]
277    #[case("d8bfd8", Purple::Thistle)]
278    #[case("thistle", Purple::Thistle)]
279    #[case("#e6e6fa", Purple::Lavender)]
280    #[case("e6e6fa", Purple::Lavender)]
281    #[case("lavender", Purple::Lavender)]
282    #[case("#ffc0cb", Purple::Pink)]
283    #[case("ffc0cb", Purple::Pink)]
284    #[case("pink", Purple::Pink)]
285    #[case("#c71585", Purple::MediumVioletRed)]
286    #[case("c71585", Purple::MediumVioletRed)]
287    #[case("mediumvioletred", Purple::MediumVioletRed)]
288    #[case("#db7093", Purple::PaleVioletRed)]
289    #[case("db7093", Purple::PaleVioletRed)]
290    #[case("palevioletred", Purple::PaleVioletRed)]
291    #[case("deeppink", Purple::DeepPink)]
292    #[case("ff1493", Purple::DeepPink)]
293    #[case("deeppink", Purple::DeepPink)]
294    #[case("#ff69b4", Purple::HotPink)]
295    #[case("ff69b4", Purple::HotPink)]
296    #[case("hotpink", Purple::HotPink)]
297    #[case("#ffb6c1", Purple::LightPink)]
298    #[case("ffb6c1", Purple::LightPink)]
299    #[case("lightpink", Purple::LightPink)]
300    fn test_from_str(#[case] input: &str, #[case] expected: Purple) {
301        assert_eq!(expected, Purple::from_str(input).unwrap())
302    }
303
304    #[rstest]
305    #[case("#4b0082", Some(Purple::Indigo))]
306    #[case("4b0082", Some(Purple::Indigo))]
307    #[case("indigo", Some(Purple::Indigo))]
308    #[case("#800080", Some(Purple::Purple))]
309    #[case("800080", Some(Purple::Purple))]
310    #[case("purple", Some(Purple::Purple))]
311    #[case("#8b008b", Some(Purple::DarkMagenta))]
312    #[case("8b008b", Some(Purple::DarkMagenta))]
313    #[case("darkmagenta", Some(Purple::DarkMagenta))]
314    #[case("#9400d3", Some(Purple::DarkViolet))]
315    #[case("9400d3", Some(Purple::DarkViolet))]
316    #[case("darkviolet", Some(Purple::DarkViolet))]
317    #[case("#483d8b", Some(Purple::DarkSlateBlue))]
318    #[case("483d8b", Some(Purple::DarkSlateBlue))]
319    #[case("darkslateblue", Some(Purple::DarkSlateBlue))]
320    #[case("#8a2be2", Some(Purple::BlueViolet))]
321    #[case("8a2be2", Some(Purple::BlueViolet))]
322    #[case("blueviolet", Some(Purple::BlueViolet))]
323    #[case("#9932cc", Some(Purple::DarkOrchid))]
324    #[case("9932cc", Some(Purple::DarkOrchid))]
325    #[case("darkorchid", Some(Purple::DarkOrchid))]
326    #[case("#a020f0", Some(Purple::Fuchsia))]
327    #[case("a020f0", Some(Purple::Fuchsia))]
328    #[case("fuchsia", Some(Purple::Fuchsia))]
329    #[case("#ff00ff", Some(Purple::Magenta))]
330    #[case("ff00ff", Some(Purple::Magenta))]
331    #[case("magenta", Some(Purple::Magenta))]
332    #[case("#6a5acd", Some(Purple::SlateBlue))]
333    #[case("6a5acd", Some(Purple::SlateBlue))]
334    #[case("slateblue", Some(Purple::SlateBlue))]
335    #[case("#7b68ee", Some(Purple::MediumSlateBlue))]
336    #[case("7b68ee", Some(Purple::MediumSlateBlue))]
337    #[case("mediumslateblue", Some(Purple::MediumSlateBlue))]
338    #[case("#ba55d3", Some(Purple::MediumOrchid))]
339    #[case("ba55d3", Some(Purple::MediumOrchid))]
340    #[case("mediumorchid", Some(Purple::MediumOrchid))]
341    #[case("#9370db", Some(Purple::MediumPurple))]
342    #[case("9370db", Some(Purple::MediumPurple))]
343    #[case("mediumpurple", Some(Purple::MediumPurple))]
344    #[case("#da70d6", Some(Purple::Orchid))]
345    #[case("da70d6", Some(Purple::Orchid))]
346    #[case("orchid", Some(Purple::Orchid))]
347    #[case("#ee82ee", Some(Purple::Violet))]
348    #[case("ee82ee", Some(Purple::Violet))]
349    #[case("violet", Some(Purple::Violet))]
350    #[case("#dda0dd", Some(Purple::Plum))]
351    #[case("dda0dd", Some(Purple::Plum))]
352    #[case("plum", Some(Purple::Plum))]
353    #[case("#d8bfd8", Some(Purple::Thistle))]
354    #[case("d8bfd8", Some(Purple::Thistle))]
355    #[case("thistle", Some(Purple::Thistle))]
356    #[case("#e6e6fa", Some(Purple::Lavender))]
357    #[case("e6e6fa", Some(Purple::Lavender))]
358    #[case("lavender", Some(Purple::Lavender))]
359    #[case("#ffc0cb", Some(Purple::Pink))]
360    #[case("ffc0cb", Some(Purple::Pink))]
361    #[case("pink", Some(Purple::Pink))]
362    #[case("#c71585", Some(Purple::MediumVioletRed))]
363    #[case("c71585", Some(Purple::MediumVioletRed))]
364    #[case("mediumvioletred", Some(Purple::MediumVioletRed))]
365    #[case("#db7093", Some(Purple::PaleVioletRed))]
366    #[case("db7093", Some(Purple::PaleVioletRed))]
367    #[case("palevioletred", Some(Purple::PaleVioletRed))]
368    #[case("deeppink", Some(Purple::DeepPink))]
369    #[case("ff1493", Some(Purple::DeepPink))]
370    #[case("deeppink", Some(Purple::DeepPink))]
371    #[case("#ff69b4", Some(Purple::HotPink))]
372    #[case("ff69b4", Some(Purple::HotPink))]
373    #[case("hotpink", Some(Purple::HotPink))]
374    #[case("#ffb6c1", Some(Purple::LightPink))]
375    #[case("ffb6c1", Some(Purple::LightPink))]
376    #[case("lightpink", Some(Purple::LightPink))]
377    #[case("012345", None)]
378    fn test_name_colour(#[case] input: &str, #[case] expected: Option<Purple>) {
379        assert_eq!(expected, Purple::name_colour(input))
380    }
381}