1use std::fmt;
5
6use rgb::Rgb;
7use strum::EnumCount;
8use tinyrand::{RandRange, StdRand};
9
10use super::ExtendedColour;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumCount)]
14#[allow(missing_docs)]
15pub enum Yellow {
16 Gold,
17 DarkGoldenrod,
18 Goldenrod,
19 PaleGoldenrod,
20 DarkKhaki,
21 Khaki,
22 Yellow,
23 YellowGreen,
24 PeachPuff,
25 Moccasin,
26 PapayaWhip,
27 LightGoldenrodYellow,
28 LemonChiffon,
29 LightYellow,
30}
31
32impl fmt::Display for Yellow {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 Self::Gold => write!(f, "#FFD700"),
36 Self::DarkGoldenrod => write!(f, "#B8860B"),
37 Self::Goldenrod => write!(f, "#DAA520"),
38 Self::PaleGoldenrod => write!(f, "#EEE8AA"),
39 Self::PeachPuff => write!(f, "#FFDAB9"),
40 Self::Moccasin => write!(f, "#FFE4B5"),
41 Self::PapayaWhip => write!(f, "#FFEFD5"),
42 Self::DarkKhaki => write!(f, "#BDB76B"),
43 Self::LemonChiffon => write!(f, "#FFFACD"),
44 Self::LightGoldenrodYellow => write!(f, "#FAFAD2"),
45 Self::Khaki => write!(f, "#F0E68C"),
46 Self::Yellow => write!(f, "#FFFF00"),
47 Self::YellowGreen => write!(f, "#9ACD32"),
48 Self::LightYellow => write!(f, "#FFFFE0"),
49 }
50 }
51}
52
53impl_colour_methods!(Yellow);
54
55impl Yellow {
56 pub fn parse(name: &str) -> Option<Self> {
69 match name.to_lowercase().as_str() {
70 "#ffd700" | "ffd700" | "gold" => Some(Self::Gold),
71 "#b8860b" | "b8860b" | "darkgoldenrod" => Some(Self::DarkGoldenrod),
72 "#dab500" | "dab500" | "goldenrod" => Some(Self::Goldenrod),
73 "#eee8aa" | "eee8aa" | "palegoldenrod" => Some(Self::PaleGoldenrod),
74 "#bdb76b" | "bdb76b" | "darkkhaki" => Some(Self::DarkKhaki),
75 "#f0e68c" | "f0e68c" | "khaki" => Some(Self::Khaki),
76 "#ffff00" | "ffff00" | "yellow" => Some(Self::Yellow),
77 "#9acd32" | "9acd32" | "yellowgreen" => Some(Self::YellowGreen),
78 "#ffdab9" | "ffdab9" | "peachpuff" => Some(Self::PeachPuff),
79 "#ffe4b5" | "ffe4b5" | "moccasin" => Some(Self::Moccasin),
80 "#ffefd5" | "ffefd5" | "papayawhip" => Some(Self::PapayaWhip),
81 "#fffacd" | "fffacd" | "lemonchiffon" => Some(Self::LemonChiffon),
82 "#fafad2" | "fafad2" | "lightgoldenrodyellow" => Some(Self::LightGoldenrodYellow),
83 "#ffffe0" | "ffffe0" | "lightyellow" => Some(Self::LightYellow),
84 _ => None,
85 }
86 }
87
88 pub fn random() -> Self {
100 let mut rand = StdRand::default();
101
102 match rand.next_range(0..Self::COUNT) {
103 0 => Self::Gold,
104 1 => Self::DarkGoldenrod,
105 2 => Self::Goldenrod,
106 3 => Self::PaleGoldenrod,
107 4 => Self::PeachPuff,
108 5 => Self::Moccasin,
109 6 => Self::PapayaWhip,
110 7 => Self::DarkKhaki,
111 8 => Self::LemonChiffon,
112 9 => Self::LightGoldenrodYellow,
113 10 => Self::Khaki,
114 11 => Self::Yellow,
115 12 => Self::YellowGreen,
116 13 => Self::LightYellow,
117 _ => Self::Yellow,
118 }
119 }
120}
121
122impl ExtendedColour for Yellow {}
123
124#[cfg(test)]
125mod tests {
126 use std::str::FromStr;
127
128 use crate::Prefix;
129
130 use super::*;
131 use rstest::rstest;
132
133 #[rstest]
134 #[case(Yellow::Gold, "rgb(255,215,0)")]
135 #[case(Yellow::DarkGoldenrod, "rgb(184,134,11)")]
136 #[case(Yellow::Goldenrod, "rgb(218,165,32)")]
137 #[case(Yellow::PaleGoldenrod, "rgb(238,232,170)")]
138 #[case(Yellow::DarkKhaki, "rgb(189,183,107)")]
139 #[case(Yellow::Khaki, "rgb(240,230,140)")]
140 #[case(Yellow::Yellow, "rgb(255,255,0)")]
141 #[case(Yellow::YellowGreen, "rgb(154,205,50)")]
142 #[case(Yellow::PeachPuff, "rgb(255,218,185)")]
143 #[case(Yellow::Moccasin, "rgb(255,228,181)")]
144 #[case(Yellow::PapayaWhip, "rgb(255,239,213)")]
145 #[case(Yellow::LemonChiffon, "rgb(255,250,205)")]
146 #[case(Yellow::LightGoldenrodYellow, "rgb(250,250,210)")]
147 #[case(Yellow::LightYellow, "rgb(255,255,224)")]
148 fn test_rgb_string(#[case] colour: Yellow, #[case] expected: String) {
149 let rgb_colour = colour.to_rgb();
150 let string = rgb_colour.to_string();
151
152 assert_eq!(expected, string);
153 }
154
155 #[rstest]
156 #[case(Yellow::Gold, "FFD700")]
157 #[case(Yellow::DarkGoldenrod, "B8860B")]
158 #[case(Yellow::Goldenrod, "DAA520")]
159 #[case(Yellow::PaleGoldenrod, "EEE8AA")]
160 #[case(Yellow::DarkKhaki, "BDB76B")]
161 #[case(Yellow::Khaki, "F0E68C")]
162 #[case(Yellow::Yellow, "FFFF00")]
163 #[case(Yellow::YellowGreen, "9ACD32")]
164 #[case(Yellow::PeachPuff, "FFDAB9")]
165 #[case(Yellow::Moccasin, "FFE4B5")]
166 #[case(Yellow::PapayaWhip, "FFEFD5")]
167 #[case(Yellow::LemonChiffon, "FFFACD")]
168 #[case(Yellow::LightGoldenrodYellow, "FAFAD2")]
169 #[case(Yellow::LightYellow, "FFFFE0")]
170 fn test_hex_triplet_string(
171 #[case] colour: Yellow,
172 #[values(Prefix::None, Prefix::Hash)] prefix: Prefix,
173 #[case] expected: String,
174 ) {
175 let prefix_string = match prefix {
176 Prefix::None => "".to_string(),
177 Prefix::Hash => "#".to_string(),
178 };
179
180 let expected = format!("{prefix_string}{expected}");
181
182 let hex_colour = colour.to_hex_triplet(prefix);
183
184 assert_eq!(expected, hex_colour);
185 }
186
187 #[rstest]
188 #[case("#ffd700", Yellow::Gold)]
189 #[case("ffd700", Yellow::Gold)]
190 #[case("Gold", Yellow::Gold)]
191 #[case("#b8860b", Yellow::DarkGoldenrod)]
192 #[case("b8860b", Yellow::DarkGoldenrod)]
193 #[case("DarkGoldenRod", Yellow::DarkGoldenrod)]
194 #[case("#dab500", Yellow::Goldenrod)]
195 #[case("dab500", Yellow::Goldenrod)]
196 #[case("GoldenRod", Yellow::Goldenrod)]
197 #[case("#eee8aa", Yellow::PaleGoldenrod)]
198 #[case("eee8aa", Yellow::PaleGoldenrod)]
199 #[case("PaleGoldenRod", Yellow::PaleGoldenrod)]
200 #[case("#bdb76b", Yellow::DarkKhaki)]
201 #[case("bdb76b", Yellow::DarkKhaki)]
202 #[case("DarkKhaki", Yellow::DarkKhaki)]
203 #[case("#f0e68c", Yellow::Khaki)]
204 #[case("f0e68c", Yellow::Khaki)]
205 #[case("Khaki", Yellow::Khaki)]
206 #[case("#ffff00", Yellow::Yellow)]
207 #[case("ffff00", Yellow::Yellow)]
208 #[case("Yellow", Yellow::Yellow)]
209 #[case("#9acd32", Yellow::YellowGreen)]
210 #[case("9acd32", Yellow::YellowGreen)]
211 #[case("YellowGreen", Yellow::YellowGreen)]
212 #[case("#ffdab9", Yellow::PeachPuff)]
213 #[case("ffdab9", Yellow::PeachPuff)]
214 #[case("PeachPuff", Yellow::PeachPuff)]
215 #[case("#ffe4b5", Yellow::Moccasin)]
216 #[case("ffe4b5", Yellow::Moccasin)]
217 #[case("Moccasin", Yellow::Moccasin)]
218 #[case("#ffefd5", Yellow::PapayaWhip)]
219 #[case("ffefd5", Yellow::PapayaWhip)]
220 #[case("PapayaWhip", Yellow::PapayaWhip)]
221 #[case("#fffacd", Yellow::LemonChiffon)]
222 #[case("fffacd", Yellow::LemonChiffon)]
223 #[case("LemonChiffon", Yellow::LemonChiffon)]
224 #[case("#fafad2", Yellow::LightGoldenrodYellow)]
225 #[case("fafad2", Yellow::LightGoldenrodYellow)]
226 #[case("LightGoldenrodYellow", Yellow::LightGoldenrodYellow)]
227 #[case("#ffffe0", Yellow::LightYellow)]
228 #[case("ffffe0", Yellow::LightYellow)]
229 #[case("LightYellow", Yellow::LightYellow)]
230 fn test_from_str(#[case] input: &str, #[case] expected: Yellow) {
231 assert_eq!(expected, Yellow::from_str(input).unwrap())
232 }
233
234 #[rstest]
235 #[case("#ffd700", Some(Yellow::Gold))]
236 #[case("ffd700", Some(Yellow::Gold))]
237 #[case("Gold", Some(Yellow::Gold))]
238 #[case("#b8860b", Some(Yellow::DarkGoldenrod))]
239 #[case("b8860b", Some(Yellow::DarkGoldenrod))]
240 #[case("DarkGoldenRod", Some(Yellow::DarkGoldenrod))]
241 #[case("#dab500", Some(Yellow::Goldenrod))]
242 #[case("dab500", Some(Yellow::Goldenrod))]
243 #[case("GoldenRod", Some(Yellow::Goldenrod))]
244 #[case("#eee8aa", Some(Yellow::PaleGoldenrod))]
245 #[case("eee8aa", Some(Yellow::PaleGoldenrod))]
246 #[case("PaleGoldenRod", Some(Yellow::PaleGoldenrod))]
247 #[case("#bdb76b", Some(Yellow::DarkKhaki))]
248 #[case("bdb76b", Some(Yellow::DarkKhaki))]
249 #[case("DarkKhaki", Some(Yellow::DarkKhaki))]
250 #[case("#f0e68c", Some(Yellow::Khaki))]
251 #[case("f0e68c", Some(Yellow::Khaki))]
252 #[case("Khaki", Some(Yellow::Khaki))]
253 #[case("#ffff00", Some(Yellow::Yellow))]
254 #[case("ffff00", Some(Yellow::Yellow))]
255 #[case("Yellow", Some(Yellow::Yellow))]
256 #[case("#9acd32", Some(Yellow::YellowGreen))]
257 #[case("9acd32", Some(Yellow::YellowGreen))]
258 #[case("YellowGreen", Some(Yellow::YellowGreen))]
259 #[case("#ffdab9", Some(Yellow::PeachPuff))]
260 #[case("ffdab9", Some(Yellow::PeachPuff))]
261 #[case("PeachPuff", Some(Yellow::PeachPuff))]
262 #[case("#ffe4b5", Some(Yellow::Moccasin))]
263 #[case("ffe4b5", Some(Yellow::Moccasin))]
264 #[case("Moccasin", Some(Yellow::Moccasin))]
265 #[case("#ffefd5", Some(Yellow::PapayaWhip))]
266 #[case("ffefd5", Some(Yellow::PapayaWhip))]
267 #[case("PapayaWhip", Some(Yellow::PapayaWhip))]
268 #[case("#fffacd", Some(Yellow::LemonChiffon))]
269 #[case("fffacd", Some(Yellow::LemonChiffon))]
270 #[case("LemonChiffon", Some(Yellow::LemonChiffon))]
271 #[case("#fafad2", Some(Yellow::LightGoldenrodYellow))]
272 #[case("fafad2", Some(Yellow::LightGoldenrodYellow))]
273 #[case("LightGoldenrodYellow", Some(Yellow::LightGoldenrodYellow))]
274 #[case("#ffffe0", Some(Yellow::LightYellow))]
275 #[case("ffffe0", Some(Yellow::LightYellow))]
276 #[case("LightYellow", Some(Yellow::LightYellow))]
277 #[case("012345", None)]
278 fn test_name_colour(#[case] input: &str, #[case] expected: Option<Yellow>) {
279 assert_eq!(expected, Yellow::name_colour(input))
280 }
281}