1use std::fmt::{Display, Formatter};
2use std::str::FromStr;
3
4use crate::exploration::shared::codex_regex::CODEX_REGEX;
5use crate::from_str_deserialize_impl;
6use serde::Serialize;
7use thiserror::Error;
8
9#[derive(Debug, Serialize, Clone, PartialEq, Eq, Hash)]
11#[cfg_attr(not(feature = "allow-unknown"), non_exhaustive)]
12pub enum CodexStarClassEntry {
13 ATypes,
14 ATypeStar,
15 ATypeGiant,
16 ATypeSupergiant,
17 ATypeHypergiant,
18
19 AeBeTypes,
20 AeBeTypeStar,
21 AeBeTypeGiant,
22 AeBeTypeSupergiant,
23 AeBeTypeHypergiant,
24
25 BTypes,
26 BTypeStar,
27 BTypeGiant,
28 BTypeSupergiant,
29 BTypeHypergiant,
30
31 CTypes,
32 CTypeStar,
33 CTypeGiant,
34 CTypeSupergiant,
35 CTypeHypergiant,
36
37 CHTypes,
38 CHTypeStar,
39 CHTypeGiant,
40 CHTypeSupergiant,
41 CHTypeHypergiant,
42
43 CHDTypes,
44 CHDTypeStar,
45 CHDTypeGiant,
46 CHDTypeSupergiant,
47 CHDTypeHypergiant,
48
49 CJTypes,
50 CJTypeStar,
51 CJTypeGiant,
52 CJTypeSupergiant,
53 CJTypeHypergiant,
54
55 CNTypes,
56 CNTypeStar,
57 CNTypeGiant,
58 CNTypeSupergiant,
59 CNTypeHypergiant,
60
61 CSTypes,
62 CSTypeStar,
63 CSTypeGiant,
64 CSTypeSupergiant,
65 CSTypeHypergiant,
66
67 DType,
68
69 DAType,
70 DATypeHypergiant,
71
72 DABType,
73 DAOType,
74 DAVType,
75 DAZType,
76 DBType,
77 DBVType,
78 DBZType,
79 DCType,
80 DCVType,
81
82 DOType,
83 DOVType,
84 DQType,
85 DXType,
86
87 FTypes,
88 FTypeStar,
89 FTypeGiant,
90 FTypeSupergiant,
91 FTypeHypergiant,
92
93 GTypes,
94 GTypeStar,
95 GTypeGiant,
96 GTypeSupergiant,
97 GTypeHypergiant,
98
99 KTypes,
100 KTypeStar,
101 KTypeGiant,
102 KTypeSupergiant,
103 KTypeHypergiant,
104
105 LTypes,
106 LTypeStar,
107 LTypeGiant,
108 LTypeSupergiant,
109 LTypeHypergiant,
110
111 MTypes,
112 MTypeStar,
113 MTypeGiant,
114 MTypeSupergiant,
115 MTypeHypergiant,
116
117 MSTypes,
118 MSTypeStar,
119 MSTypeGiant,
120 MSTypeSupergiant,
121 MSTypeHypergiant,
122
123 OTypes,
124 OTypeStar,
125 OTypeGiant,
126 OTypeSupergiant,
127 OTypeHypergiant,
128
129 STypes,
130 STypeStar,
131 STypeGiant,
132 STypeSupergiant,
133 STypeHypergiant,
134
135 TTypes,
136 TTypeStar,
137 TTypeGiant,
138 TTypeSupergiant,
139 TTypeHypergiant,
140
141 TTSTypes,
142 TTSTypeStar,
143 TTSTypeGiant,
144 TTSTypeSupergiant,
145 TTSTypeHypergiant,
146
147 WType,
148 WCType,
149 WNType,
150 WNCType,
151 WOType,
152
153 YTypes,
154 YTypeStar,
155 YTypeGiant,
156 YTypeSupergiant,
157 YTypeHypergiant,
158
159 WhiteDwarfs,
160 WolfRayetStars,
161
162 NeutronStars,
163 BlackHole,
164
165 #[cfg(feature = "allow-unknown")]
166 #[cfg_attr(docsrs, doc(cfg(feature = "allow-unknown")))]
167 Unknown(String),
168}
169
170impl CodexStarClassEntry {
171 #[cfg(feature = "allow-unknown")]
173 #[cfg_attr(docsrs, doc(cfg(feature = "allow-unknown")))]
174 pub fn is_unknown(&self) -> bool {
175 matches!(self, CodexStarClassEntry::Unknown(_))
176 }
177}
178
179#[derive(Debug, Error)]
181pub enum CodexStarClassError {
182 #[error("Failed to parse star class codex entry: '{0}'")]
183 FailedToParse(String),
184
185 #[error("Unknown star class codex entry: '{0}'")]
186 UnknownEntry(String),
187}
188
189impl FromStr for CodexStarClassEntry {
190 type Err = CodexStarClassError;
191
192 fn from_str(s: &str) -> Result<Self, Self::Err> {
193 let Some(captures) = CODEX_REGEX.captures(s) else {
194 return Err(CodexStarClassError::FailedToParse(s.to_string()));
195 };
196
197 let string: &str = &captures
198 .get(1)
199 .expect("Should have been captured already")
200 .as_str()
201 .to_ascii_lowercase();
202
203 Ok(match string {
204 "a_types" => CodexStarClassEntry::ATypes,
205 "a_type" => CodexStarClassEntry::ATypeStar,
206 "a_typegiant" => CodexStarClassEntry::ATypeGiant,
207 "a_typesupergiant" => CodexStarClassEntry::ATypeSupergiant,
208 "a_typehypergiant" => CodexStarClassEntry::ATypeHypergiant,
209
210 "aebe_types" => CodexStarClassEntry::AeBeTypes,
211 "aebe_type" => CodexStarClassEntry::AeBeTypeStar,
212 "aebe_typegiant" => CodexStarClassEntry::AeBeTypeGiant,
213 "aebe_typesupergiant" => CodexStarClassEntry::AeBeTypeSupergiant,
214 "aebe_typehypergiant" => CodexStarClassEntry::AeBeTypeHypergiant,
215
216 "b_types" => CodexStarClassEntry::BTypes,
217 "b_type" => CodexStarClassEntry::BTypeStar,
218 "b_typegiant" => CodexStarClassEntry::BTypeGiant,
219 "b_typesupergiant" => CodexStarClassEntry::BTypeSupergiant,
220 "b_typehypergiant" => CodexStarClassEntry::BTypeHypergiant,
221
222 "c_types" => CodexStarClassEntry::CTypes,
223 "c_type" => CodexStarClassEntry::CTypeStar,
224 "c_typegiant" => CodexStarClassEntry::CTypeGiant,
225 "c_typesupergiant" => CodexStarClassEntry::CTypeSupergiant,
226 "c_typehypergiant" => CodexStarClassEntry::CTypeHypergiant,
227
228 "ch_types" => CodexStarClassEntry::CHTypes,
229 "ch_type" => CodexStarClassEntry::CHTypeStar,
230 "ch_typegiant" => CodexStarClassEntry::CHTypeGiant,
231 "ch_typesupergiant" => CodexStarClassEntry::CHTypeSupergiant,
232 "ch_typehypergiant" => CodexStarClassEntry::CHTypeHypergiant,
233
234 "chd_types" => CodexStarClassEntry::CHDTypes,
235 "chd_type" => CodexStarClassEntry::CHDTypeStar,
236 "chd_typegiant" => CodexStarClassEntry::CHDTypeGiant,
237 "chd_typesupergiant" => CodexStarClassEntry::CHDTypeSupergiant,
238 "chd_typehypergiant" => CodexStarClassEntry::CHDTypeHypergiant,
239
240 "cj_types" => CodexStarClassEntry::CJTypes,
241 "cj_type" => CodexStarClassEntry::CJTypeStar,
242 "cj_typegiant" => CodexStarClassEntry::CJTypeGiant,
243 "cj_typesupergiant" => CodexStarClassEntry::CJTypeSupergiant,
244 "cj_typehypergiant" => CodexStarClassEntry::CJTypeHypergiant,
245
246 "cn_types" => CodexStarClassEntry::CNTypes,
247 "cn_type" => CodexStarClassEntry::CNTypeStar,
248 "cn_typegiant" => CodexStarClassEntry::CNTypeGiant,
249 "cn_typesupergiant" => CodexStarClassEntry::CNTypeSupergiant,
250 "cn_typehypergiant" => CodexStarClassEntry::CNTypeHypergiant,
251
252 "cs_types" => CodexStarClassEntry::CSTypes,
253 "cs_type" => CodexStarClassEntry::CSTypeStar,
254 "cs_typegiant" => CodexStarClassEntry::CSTypeGiant,
255 "cs_typesupergiant" => CodexStarClassEntry::CSTypeSupergiant,
256 "cs_typehypergiant" => CodexStarClassEntry::CSTypeHypergiant,
257
258 "d_type" => CodexStarClassEntry::DType,
259
260 "da_type" => CodexStarClassEntry::DAType,
261 "da_typehypergiant" => CodexStarClassEntry::DATypeHypergiant,
262 "dab_type" => CodexStarClassEntry::DABType,
263 "dao_type" => CodexStarClassEntry::DAOType,
264 "dav_type" => CodexStarClassEntry::DAVType,
265 "daz_type" => CodexStarClassEntry::DAZType,
266 "db_type" => CodexStarClassEntry::DBType,
267 "dbv_type" => CodexStarClassEntry::DBVType,
268 "dbz_type" => CodexStarClassEntry::DBZType,
269 "dc_type" => CodexStarClassEntry::DCType,
270 "dcv_type" => CodexStarClassEntry::DCVType,
271
272 "do_type" => CodexStarClassEntry::DOType,
273 "dov_type" => CodexStarClassEntry::DOVType,
274 "dq_type" => CodexStarClassEntry::DQType,
275 "dx_type" => CodexStarClassEntry::DXType,
276
277 "f_types" => CodexStarClassEntry::FTypes,
278 "f_type" => CodexStarClassEntry::FTypeStar,
279 "f_typegiant" => CodexStarClassEntry::FTypeGiant,
280 "f_typesupergiant" => CodexStarClassEntry::FTypeSupergiant,
281 "f_typehypergiant" => CodexStarClassEntry::FTypeHypergiant,
282
283 "g_types" => CodexStarClassEntry::GTypes,
284 "g_type" => CodexStarClassEntry::GTypeStar,
285 "g_typegiant" => CodexStarClassEntry::GTypeGiant,
286 "g_typesupergiant" => CodexStarClassEntry::GTypeSupergiant,
287 "g_typehypergiant" => CodexStarClassEntry::GTypeHypergiant,
288
289 "k_types" => CodexStarClassEntry::KTypes,
290 "k_type" => CodexStarClassEntry::KTypeStar,
291 "k_typegiant" => CodexStarClassEntry::KTypeGiant,
292 "k_typesupergiant" => CodexStarClassEntry::KTypeSupergiant,
293 "k_typehypergiant" => CodexStarClassEntry::KTypeHypergiant,
294
295 "l_types" => CodexStarClassEntry::LTypes,
296 "l_type" => CodexStarClassEntry::LTypeStar,
297 "l_typegiant" => CodexStarClassEntry::LTypeGiant,
298 "l_typesupergiant" => CodexStarClassEntry::LTypeSupergiant,
299 "l_typehypergiant" => CodexStarClassEntry::LTypeHypergiant,
300
301 "m_types" => CodexStarClassEntry::MTypes,
302 "m_type" => CodexStarClassEntry::MTypeStar,
303 "m_typegiant" => CodexStarClassEntry::MTypeGiant,
304 "m_typesupergiant" => CodexStarClassEntry::MTypeSupergiant,
305 "m_typehypergiant" => CodexStarClassEntry::MTypeHypergiant,
306
307 "ms_types" => CodexStarClassEntry::MSTypes,
308 "ms_type" => CodexStarClassEntry::MSTypeStar,
309 "ms_typegiant" => CodexStarClassEntry::MSTypeGiant,
310 "ms_typesupergiant" => CodexStarClassEntry::MSTypeSupergiant,
311 "ms_typehypergiant" => CodexStarClassEntry::MSTypeHypergiant,
312
313 "o_types" => CodexStarClassEntry::MSTypes,
314 "o_type" => CodexStarClassEntry::MSTypeStar,
315 "o_typegiant" => CodexStarClassEntry::MSTypeGiant,
316 "o_typesupergiant" => CodexStarClassEntry::MSTypeSupergiant,
317 "o_typehypergiant" => CodexStarClassEntry::MSTypeHypergiant,
318
319 "s_types" => CodexStarClassEntry::STypes,
320 "s_type" => CodexStarClassEntry::STypeStar,
321 "s_typegiant" => CodexStarClassEntry::STypeGiant,
322 "s_typesupergiant" => CodexStarClassEntry::STypeSupergiant,
323 "s_typehypergiant" => CodexStarClassEntry::STypeHypergiant,
324
325 "t_types" => CodexStarClassEntry::TTypes,
326 "t_type" => CodexStarClassEntry::TTypeStar,
327 "t_typegiant" => CodexStarClassEntry::TTypeGiant,
328 "t_typesupergiant" => CodexStarClassEntry::TTypeSupergiant,
329 "t_typehypergiant" => CodexStarClassEntry::TTypeHypergiant,
330
331 "tts_types" => CodexStarClassEntry::TTypes,
332 "tts_type" => CodexStarClassEntry::TTypeStar,
333 "tts_typegiant" => CodexStarClassEntry::TTypeGiant,
334 "tts_typesupergiant" => CodexStarClassEntry::TTypeSupergiant,
335 "tts_typehypergiant" => CodexStarClassEntry::TTypeHypergiant,
336
337 "w_type" => CodexStarClassEntry::WType,
338 "wc_type" => CodexStarClassEntry::WCType,
339 "wn_type" => CodexStarClassEntry::WNType,
340 "wnc_type" => CodexStarClassEntry::WNCType,
341 "wo_type" => CodexStarClassEntry::WOType,
342
343 "y_types" => CodexStarClassEntry::YTypes,
344 "y_type" => CodexStarClassEntry::YTypeStar,
345 "y_typegiant" => CodexStarClassEntry::YTypeGiant,
346 "y_typesupergiant" => CodexStarClassEntry::YTypeSupergiant,
347 "y_typehypergiant" => CodexStarClassEntry::YTypeHypergiant,
348
349 "white_dwarfs" => CodexStarClassEntry::WhiteDwarfs,
350 "wolf_rayet_stars" => CodexStarClassEntry::WolfRayetStars,
351
352 "black_holes" => CodexStarClassEntry::BlackHole,
360 "neutron_stars" => CodexStarClassEntry::NeutronStars,
361
362 #[cfg(feature = "allow-unknown")]
363 _ => CodexStarClassEntry::Unknown(string.to_string()),
364
365 #[cfg(not(feature = "allow-unknown"))]
366 _ => return Err(CodexStarClassError::UnknownEntry(s.to_string())),
367 })
368 }
380}
381
382from_str_deserialize_impl!(CodexStarClassEntry);
383
384impl Display for CodexStarClassEntry {
385 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
386 write!(
387 f,
388 "{}",
389 match self {
390 CodexStarClassEntry::ATypes => "A Type Stars",
391 CodexStarClassEntry::ATypeStar => "A Type Star",
392 CodexStarClassEntry::ATypeGiant => "A Type Giant",
393 CodexStarClassEntry::ATypeSupergiant => "A Type Supergiant",
394 CodexStarClassEntry::ATypeHypergiant => "A Type Hypergiant",
395
396 CodexStarClassEntry::AeBeTypes => "AeBe Type Stars",
397 CodexStarClassEntry::AeBeTypeStar => "AeBe Type Star",
398 CodexStarClassEntry::AeBeTypeGiant => "AeBe Type Giant",
399 CodexStarClassEntry::AeBeTypeSupergiant => "AeBe Type Supergiant",
400 CodexStarClassEntry::AeBeTypeHypergiant => "AeBe Type Hypergiant",
401
402 CodexStarClassEntry::BTypes => "B Type Stars",
403 CodexStarClassEntry::BTypeStar => "B Type Star",
404 CodexStarClassEntry::BTypeGiant => "B Type Giant",
405 CodexStarClassEntry::BTypeSupergiant => "B Type Supergiant",
406 CodexStarClassEntry::BTypeHypergiant => "B Type Hypergiant",
407
408 CodexStarClassEntry::CTypes => "C Type Stars",
409 CodexStarClassEntry::CTypeStar => "C Type Star",
410 CodexStarClassEntry::CTypeGiant => "C Type Giant",
411 CodexStarClassEntry::CTypeSupergiant => "C Type Supergiant",
412 CodexStarClassEntry::CTypeHypergiant => "C Type Hypergiant",
413
414 CodexStarClassEntry::CHTypes => "CH Type Stars",
415 CodexStarClassEntry::CHTypeStar => "CH Type Star",
416 CodexStarClassEntry::CHTypeGiant => "CH Type Giant",
417 CodexStarClassEntry::CHTypeSupergiant => "CH Type Supergiant",
418 CodexStarClassEntry::CHTypeHypergiant => "CH Type Hypergiant",
419
420 CodexStarClassEntry::CHDTypes => "CHD Type Stars",
421 CodexStarClassEntry::CHDTypeStar => "CHD Type Star",
422 CodexStarClassEntry::CHDTypeGiant => "CHD Type Giant",
423 CodexStarClassEntry::CHDTypeSupergiant => "CHD Type Supergiant",
424 CodexStarClassEntry::CHDTypeHypergiant => "CHD Type Hypergiant",
425
426 CodexStarClassEntry::CJTypes => "CJ Type Stars",
427 CodexStarClassEntry::CJTypeStar => "CJ Type Star",
428 CodexStarClassEntry::CJTypeGiant => "CJ Type Giant",
429 CodexStarClassEntry::CJTypeSupergiant => "CJ Type Supergiant",
430 CodexStarClassEntry::CJTypeHypergiant => "CJ Type Hypergiant",
431
432 CodexStarClassEntry::CNTypes => "CN Type Stars",
433 CodexStarClassEntry::CNTypeStar => "CN Type Star",
434 CodexStarClassEntry::CNTypeGiant => "CN Type Giant",
435 CodexStarClassEntry::CNTypeSupergiant => "CN Type Supergiant",
436 CodexStarClassEntry::CNTypeHypergiant => "CN Type Hypergiant",
437
438 CodexStarClassEntry::CSTypes => "CS Type Stars",
439 CodexStarClassEntry::CSTypeStar => "CS Type Star",
440 CodexStarClassEntry::CSTypeGiant => "CS Type Giant",
441 CodexStarClassEntry::CSTypeSupergiant => "CS Type Supergiant",
442 CodexStarClassEntry::CSTypeHypergiant => "CS Type Hypergiant",
443
444 CodexStarClassEntry::DType => "D Type Star",
445
446 CodexStarClassEntry::DAType => "DA Type",
447 CodexStarClassEntry::DATypeHypergiant => "DA Type Hypergiant",
448 CodexStarClassEntry::DABType => "DAB Type",
449 CodexStarClassEntry::DAOType => "DAO Type",
450 CodexStarClassEntry::DAVType => "DAV Type",
451 CodexStarClassEntry::DAZType => "DAZ Type",
452 CodexStarClassEntry::DBType => "DB Type",
453 CodexStarClassEntry::DBVType => "DBV Type",
454 CodexStarClassEntry::DBZType => "DBZ Type",
455 CodexStarClassEntry::DCType => "DC Type",
456 CodexStarClassEntry::DCVType => "CV Type",
457
458 CodexStarClassEntry::DOType => "DO Type",
459 CodexStarClassEntry::DOVType => "DOV Type",
460 CodexStarClassEntry::DQType => "DQ Type",
461 CodexStarClassEntry::DXType => "DX Type",
462
463 CodexStarClassEntry::FTypes => "F Type Stars",
464 CodexStarClassEntry::FTypeStar => "F Type Star",
465 CodexStarClassEntry::FTypeGiant => "F Type Giant",
466 CodexStarClassEntry::FTypeSupergiant => "F Type Supergiant",
467 CodexStarClassEntry::FTypeHypergiant => "F Type Hypergiant",
468
469 CodexStarClassEntry::GTypes => "G Type Stars",
470 CodexStarClassEntry::GTypeStar => "G Type Star",
471 CodexStarClassEntry::GTypeGiant => "G Type Giant",
472 CodexStarClassEntry::GTypeSupergiant => "G Type Supergiant",
473 CodexStarClassEntry::GTypeHypergiant => "G Type Hypergiant",
474
475 CodexStarClassEntry::KTypes => "K Type Stars",
476 CodexStarClassEntry::KTypeStar => "K Type Star",
477 CodexStarClassEntry::KTypeGiant => "K Type Giant",
478 CodexStarClassEntry::KTypeSupergiant => "K Type Supergiant",
479 CodexStarClassEntry::KTypeHypergiant => "K Type Hypergiant",
480
481 CodexStarClassEntry::LTypes => "L Type Stars",
482 CodexStarClassEntry::LTypeStar => "L Type Star",
483 CodexStarClassEntry::LTypeGiant => "L Type Giant",
484 CodexStarClassEntry::LTypeSupergiant => "L Type Supergiant",
485 CodexStarClassEntry::LTypeHypergiant => "L Type Hypergiant",
486
487 CodexStarClassEntry::MTypes => "M Type Stars",
488 CodexStarClassEntry::MTypeStar => "M Type Star",
489 CodexStarClassEntry::MTypeGiant => "M Type Giant",
490 CodexStarClassEntry::MTypeSupergiant => "M Type Supergiant",
491 CodexStarClassEntry::MTypeHypergiant => "M Type Hypergiant",
492
493 CodexStarClassEntry::MSTypes => "MS Type Stars",
494 CodexStarClassEntry::MSTypeStar => "MS Type Star",
495 CodexStarClassEntry::MSTypeGiant => "MS Type Giant",
496 CodexStarClassEntry::MSTypeSupergiant => "MS Type Supergiant",
497 CodexStarClassEntry::MSTypeHypergiant => "MS Type Hypergiant",
498
499 CodexStarClassEntry::OTypes => "O Type Stars",
500 CodexStarClassEntry::OTypeStar => "O Type Star",
501 CodexStarClassEntry::OTypeGiant => "O Type Giant",
502 CodexStarClassEntry::OTypeSupergiant => "O Type Supergiant",
503 CodexStarClassEntry::OTypeHypergiant => "O Type Hypergiant",
504
505 CodexStarClassEntry::STypes => "S Type Stars",
506 CodexStarClassEntry::STypeStar => "S Type Star",
507 CodexStarClassEntry::STypeGiant => "S Type Giant",
508 CodexStarClassEntry::STypeSupergiant => "S Type Supergiant",
509 CodexStarClassEntry::STypeHypergiant => "S Type Hypergiant",
510
511 CodexStarClassEntry::TTypes => "T Type Stars",
512 CodexStarClassEntry::TTypeStar => "T Type Star",
513 CodexStarClassEntry::TTypeGiant => "T Type Giant",
514 CodexStarClassEntry::TTypeSupergiant => "T Type Supergiant",
515 CodexStarClassEntry::TTypeHypergiant => "T Type Hypergiant",
516
517 CodexStarClassEntry::TTSTypes => "TTS Type Stars",
518 CodexStarClassEntry::TTSTypeStar => "TTS Type Star",
519 CodexStarClassEntry::TTSTypeGiant => "TTS Type Giant",
520 CodexStarClassEntry::TTSTypeSupergiant => "TTS Type Supergiant",
521 CodexStarClassEntry::TTSTypeHypergiant => "TTS Type Hypergiant",
522
523 CodexStarClassEntry::WType => "W Type",
524 CodexStarClassEntry::WCType => "WC Type",
525 CodexStarClassEntry::WNType => "WN Type",
526 CodexStarClassEntry::WNCType => "WNC Type",
527 CodexStarClassEntry::WOType => "WO Type",
528
529 CodexStarClassEntry::YTypes => "Y Type Stars",
530 CodexStarClassEntry::YTypeStar => "Y Type Star",
531 CodexStarClassEntry::YTypeGiant => "Y Type Giant",
532 CodexStarClassEntry::YTypeSupergiant => "Y Type Supergiant",
533 CodexStarClassEntry::YTypeHypergiant => "Y Type Hypergiant",
534
535 CodexStarClassEntry::WhiteDwarfs => "White Dwarfs",
536 CodexStarClassEntry::WolfRayetStars => "Wolf-Rayet Stars",
537
538 CodexStarClassEntry::NeutronStars => "Neutron Star",
539 CodexStarClassEntry::BlackHole => "Black Hole",
540
541 #[cfg(feature = "allow-unknown")]
542 CodexStarClassEntry::Unknown(unknown) =>
543 return write!(f, "Unknown star codex entry: {unknown}"),
544 }
545 )
546 }
547}