1use crate::exploration::shared::codex_regex::CODEX_REGEX;
2use crate::from_str_deserialize_impl;
3use serde::Serialize;
4use std::fmt::{Display, Formatter};
5use std::str::FromStr;
6use thiserror::Error;
7
8#[derive(Debug, Serialize, Clone, PartialEq, Eq, Hash)]
10#[cfg_attr(not(feature = "allow-unknown"), non_exhaustive)]
11pub enum CodexPlanetEntry {
12 EarthLike,
13 AmmoniaWorlds,
14 WaterWorlds,
15 WaterGiant,
16 WaterGiantWithLife,
17 SudarskyClassI,
18 SudarskyClassII,
19 SudarskyClassIII,
20 SudarskyClassIV,
21 SudarskyClassV,
22 SupermassiveBlackHoles,
23 Helium,
24 HeliumRich,
25
26 HighMetalContent,
28 Ice,
29 MetalRich,
30 RockyIce,
31 Rocky,
32
33 MetalRichNoAtmosphere,
35 HighMetalContentNoAtmosphere,
36 IceNoAtmosphere,
37 RockyIceNoAtmosphere,
38 RockyNoAtmosphere,
39
40 DenseAmmoniaWorlds,
42 DenseWaterWorlds,
43
44 DenseHighMetalContent,
46 DenseIce,
47 DenseMetalRich,
48 DenseRockyIce,
49 DenseRocky,
50
51 StandardGiants,
53 StandardWaterWorlds,
54 StandardPlanetStandard,
55 StandardPlanetTerraformable,
56
57 StandardAmmoniaWorlds,
59 StandardGiantWithAmmoniaLife,
60 StandardGiantWithWaterLife,
61 StandardHelium,
62 StandardHeliumRich,
63 StandardWaterGiant,
64 StandardWaterGiantWithLife,
65
66 StandardHighMetalContentNoAtmosphere,
68 StandardIceNoAtmosphere,
69 StandardMetalRichNoAtmosphere,
70 StandardRockyIceNoAtmosphere,
71 StandardRockyNoAtmosphere,
72
73 StandardSudarskyClassI,
75 StandardSudarskyClassII,
76 StandardSudarskyClassIII,
77 StandardSudarskyClassIV,
78 StandardSudarskyClassV,
79
80 StandardHighMetalContent,
82 StandardIce,
83 StandardMetalRich,
84 StandardRockyIce,
85 StandardRocky,
86
87 LightAmmoniaWorlds,
89 LightWaterWorlds,
90
91 LightHighMetalContent,
93 LightIce,
94 LightMetalRich,
95 LightRockyIce,
96 LightRocky,
97
98 GiantWithAmmoniaLife,
100 GiantWithWaterLife,
101
102 GreenGiants,
104 GreenGiantWithAmmoniaLife,
105 GreenGiantWithWaterLife,
106 GreenSudarskyClassI,
107 GreenSudarskyClassII,
108 GreenSudarskyClassIII,
109 GreenSudarskyClassIV,
110 GreenSudarskyClassV,
111 GreenWaterGiant,
112 GreenWaterGiantWithLife,
113 GreenHelium,
114 GreenHeliumRich,
115
116 TerraformableAmmoniaWorlds,
118 TerraformableWaterWorlds,
119
120 TerraformableHighMetalContentNoAtmosphere,
122 TerraformableIceNoAtmosphere,
123 TerraformableMetalRichNoAtmosphere,
124 TerraformableRockyIceNoAtmosphere,
125 TerraformableRockyNoAtmosphere,
126
127 TerraformableHighMetalContent,
129 TerraformableIce,
130 TerraformableMetalRich,
131 TerraformableRockyIce,
132 TerraformableRocky,
133
134 #[cfg(feature = "allow-unknown")]
135 #[cfg_attr(docsrs, doc(cfg(feature = "allow-unknown")))]
136 Unknown(String),
137}
138
139impl CodexPlanetEntry {
140 #[cfg(feature = "allow-unknown")]
142 #[cfg_attr(docsrs, doc(cfg(feature = "allow-unknown")))]
143 pub fn is_unknown(&self) -> bool {
144 matches!(self, CodexPlanetEntry::Unknown(_))
145 }
146}
147
148#[derive(Debug, Error)]
149pub enum CodexPlanetError {
150 #[error("Failed to parse planet codex entry: '{0}'")]
151 FailedToParse(String),
152
153 #[error("Unknown planet codex entry: '{0}'")]
154 UnknownEntry(String),
155}
156
157impl FromStr for CodexPlanetEntry {
158 type Err = CodexPlanetError;
159
160 fn from_str(s: &str) -> Result<Self, Self::Err> {
161 let Some(captures) = CODEX_REGEX.captures(s) else {
162 return Err(CodexPlanetError::FailedToParse(s.to_string()));
163 };
164
165 let string: &str = &captures
166 .get(1)
167 .expect("Should have been captured already")
168 .as_str()
169 .to_ascii_lowercase();
170
171 Ok(match string {
173 "earth_likes" => CodexPlanetEntry::EarthLike,
174 "ammonia_worlds" => CodexPlanetEntry::AmmoniaWorlds,
175 "water_worlds" => CodexPlanetEntry::WaterWorlds,
176 "water_giant" => CodexPlanetEntry::WaterGiant,
177 "water_giant_with_life" => CodexPlanetEntry::WaterGiantWithLife,
178 "sudarsky_class_i" => CodexPlanetEntry::SudarskyClassI,
179 "sudarsky_class_ii" => CodexPlanetEntry::SudarskyClassII,
180 "sudarsky_class_iii" => CodexPlanetEntry::SudarskyClassIII,
181 "sudarsky_class_iv" => CodexPlanetEntry::SudarskyClassIV,
182 "sudarsky_class_v" => CodexPlanetEntry::SudarskyClassV,
183 "supermassiveblack_holes" => CodexPlanetEntry::SupermassiveBlackHoles,
184 "helium" => CodexPlanetEntry::Helium,
185 "helium_rich" => CodexPlanetEntry::HeliumRich,
186
187 "ter_high_metal_content" => CodexPlanetEntry::HighMetalContent,
189 "ter_ice" => CodexPlanetEntry::Ice,
190 "ter_metal_rich" => CodexPlanetEntry::MetalRich,
191 "ter_rocky_ice" => CodexPlanetEntry::RockyIce,
192 "ter_rocky" => CodexPlanetEntry::Rocky,
193
194 "metal_rich_no_atmos" => CodexPlanetEntry::MetalRichNoAtmosphere,
196 "high_metal_content_no_atmos" => CodexPlanetEntry::HighMetalContentNoAtmosphere,
197 "ice_no_atmos" => CodexPlanetEntry::IceNoAtmosphere,
198 "rocky_ice_no_atmos" => CodexPlanetEntry::RockyIceNoAtmosphere,
199 "rocky_no_atmos" => CodexPlanetEntry::RockyNoAtmosphere,
200
201 "dense_ammonia_worlds" => CodexPlanetEntry::DenseAmmoniaWorlds,
203 "dense_water_worlds" => CodexPlanetEntry::DenseWaterWorlds,
204
205 "dense_ter_high_metal_content" => CodexPlanetEntry::DenseHighMetalContent,
207 "dense_ter_ice" => CodexPlanetEntry::DenseIce,
208 "dense_ter_metal_rich" => CodexPlanetEntry::DenseMetalRich,
209 "dense_ter_rocky_ice" => CodexPlanetEntry::DenseRockyIce,
210 "dense_ter_rocky" => CodexPlanetEntry::DenseRocky,
211
212 "standard_giants" => CodexPlanetEntry::StandardGiants,
214 "standard_planetstandard" => CodexPlanetEntry::StandardPlanetStandard,
215 "standard_planetterraf" => CodexPlanetEntry::StandardPlanetTerraformable,
216 "standard_water_worlds" => CodexPlanetEntry::StandardWaterWorlds,
217
218 "standard_ammonia_worlds" => CodexPlanetEntry::StandardAmmoniaWorlds,
220 "standard_giant_with_ammonia_life" => CodexPlanetEntry::StandardGiantWithAmmoniaLife,
221 "standard_giant_with_water_life" => CodexPlanetEntry::StandardGiantWithWaterLife,
222 "standard_helium" => CodexPlanetEntry::StandardHelium,
223 "standard_helium_rich" => CodexPlanetEntry::StandardHeliumRich,
224 "standard_water_giant" => CodexPlanetEntry::StandardWaterGiant,
225 "standard_water_giant_with_life" => CodexPlanetEntry::StandardWaterGiantWithLife,
226
227 "standard_high_metal_content_no_atmos" => {
229 CodexPlanetEntry::StandardHighMetalContentNoAtmosphere
230 }
231 "standard_ice_no_atmos" => CodexPlanetEntry::StandardIceNoAtmosphere,
232 "standard_metal_rich_no_atmos" => CodexPlanetEntry::StandardMetalRichNoAtmosphere,
233 "standard_rocky_ice_no_atmos" => CodexPlanetEntry::StandardRockyIceNoAtmosphere,
234 "standard_rocky_no_atmos" => CodexPlanetEntry::StandardRockyNoAtmosphere,
235
236 "standard_sudarsky_class_i" => CodexPlanetEntry::StandardSudarskyClassI,
238 "standard_sudarsky_class_ii" => CodexPlanetEntry::StandardSudarskyClassII,
239 "standard_sudarsky_class_iii" => CodexPlanetEntry::StandardSudarskyClassIII,
240 "standard_sudarsky_class_iv" => CodexPlanetEntry::StandardSudarskyClassIV,
241 "standard_sudarsky_class_v" => CodexPlanetEntry::StandardSudarskyClassV,
242
243 "standard_ter_high_metal_content" => CodexPlanetEntry::StandardHighMetalContent,
245 "standard_ter_ice" => CodexPlanetEntry::StandardIce,
246 "standard_ter_metal_rich" => CodexPlanetEntry::StandardMetalRich,
247 "standard_ter_rocky_ice" => CodexPlanetEntry::StandardRockyIce,
248 "standard_ter_rocky" => CodexPlanetEntry::StandardRocky,
249
250 "light_ammonia_worlds" => CodexPlanetEntry::LightAmmoniaWorlds,
252 "light_water_worlds" => CodexPlanetEntry::LightWaterWorlds,
253
254 "light_ter_high_metal_content" => CodexPlanetEntry::LightHighMetalContent,
256 "light_ter_ice" => CodexPlanetEntry::LightIce,
257 "light_ter_metal_rich" => CodexPlanetEntry::LightMetalRich,
258 "light_ter_rocky_ice" => CodexPlanetEntry::LightRockyIce,
259 "light_ter_rocky" => CodexPlanetEntry::LightRocky,
260
261 "giant_with_ammonia_life" => CodexPlanetEntry::GiantWithAmmoniaLife,
263 "giant_with_water_life" => CodexPlanetEntry::GiantWithWaterLife,
264
265 "greengiants" => CodexPlanetEntry::GreenGiants,
267 "green_giant_with_ammonia_life" => CodexPlanetEntry::GreenGiantWithAmmoniaLife,
268 "green_giant_with_water_life" => CodexPlanetEntry::GreenGiantWithWaterLife,
269 "green_sudarsky_class_i" => CodexPlanetEntry::GreenSudarskyClassI,
270 "green_sudarsky_class_ii" => CodexPlanetEntry::GreenSudarskyClassII,
271 "green_sudarsky_class_iii" => CodexPlanetEntry::GreenSudarskyClassIII,
272 "green_sudarsky_class_iv" => CodexPlanetEntry::GreenSudarskyClassIV,
273 "green_sudarsky_class_v" => CodexPlanetEntry::GreenSudarskyClassV,
274 "green_water_giant" => CodexPlanetEntry::GreenWaterGiant,
275 "green_water_giant_with_life" => CodexPlanetEntry::GreenWaterGiantWithLife,
276 "green_helium" => CodexPlanetEntry::GreenHelium,
277 "green_helium_rich" => CodexPlanetEntry::GreenHeliumRich,
278
279 "trf_ammonia_worlds" => CodexPlanetEntry::TerraformableAmmoniaWorlds,
281 "trf_water_worlds" => CodexPlanetEntry::TerraformableWaterWorlds,
282
283 "trf_high_metal_content_no_atmos" => {
285 CodexPlanetEntry::TerraformableHighMetalContentNoAtmosphere
286 }
287 "trf_ice_no_atmos" => CodexPlanetEntry::TerraformableIceNoAtmosphere,
288 "trf_metal_rich_no_atmos" => CodexPlanetEntry::TerraformableMetalRichNoAtmosphere,
289 "trf_rocky_ice_no_atmos" => CodexPlanetEntry::TerraformableRockyIceNoAtmosphere,
290 "trf_rocky_no_atmos" => CodexPlanetEntry::TerraformableRockyNoAtmosphere,
291
292 "trf_ter_high_metal_content" => CodexPlanetEntry::TerraformableHighMetalContent,
294 "trf_ter_ice" => CodexPlanetEntry::TerraformableIce,
295 "trf_ter_metal_rich" => CodexPlanetEntry::TerraformableMetalRich,
296 "trf_ter_rocky_ice" => CodexPlanetEntry::TerraformableRockyIce,
297 "trf_ter_rocky" => CodexPlanetEntry::TerraformableRocky,
298
299 #[cfg(feature = "allow-unknown")]
300 _ => CodexPlanetEntry::Unknown(string.to_string()),
301
302 #[cfg(not(feature = "allow-unknown"))]
303 _ => return Err(CodexPlanetError::UnknownEntry(string.to_string())),
304 })
305 }
306}
307
308from_str_deserialize_impl!(CodexPlanetEntry);
309
310impl Display for CodexPlanetEntry {
311 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
312 write!(
313 f,
314 "{}",
315 match self {
316 CodexPlanetEntry::EarthLike => "earth_like",
317 CodexPlanetEntry::AmmoniaWorlds => "Ammonia World",
318 CodexPlanetEntry::WaterWorlds => "Water Worlds",
319 CodexPlanetEntry::WaterGiant => "Water Giant",
320 CodexPlanetEntry::WaterGiantWithLife => "Water Giant with Life",
321 CodexPlanetEntry::SudarskyClassI => "Sudarsky Class I",
322 CodexPlanetEntry::SudarskyClassII => "Sudarsky Class II",
323 CodexPlanetEntry::SudarskyClassIII => "Sudarsky Class III",
324 CodexPlanetEntry::SudarskyClassIV => "Sudarsky Class IV",
325 CodexPlanetEntry::SudarskyClassV => "Sudarsky Class V",
326 CodexPlanetEntry::SupermassiveBlackHoles => "Supermassive Black Holes",
327 CodexPlanetEntry::Helium => "Helium Planet",
328 CodexPlanetEntry::HeliumRich => "Helium-Rich Planet",
329
330 CodexPlanetEntry::DenseAmmoniaWorlds => "Dense Ammonia World",
331 CodexPlanetEntry::DenseWaterWorlds => "Dense Water Worlds",
332 CodexPlanetEntry::DenseHighMetalContent => "Dense High Metal Content Planet",
333 CodexPlanetEntry::DenseIce => "Dense Ice Planet",
334 CodexPlanetEntry::DenseMetalRich => "Dense Metal-Rich Planet",
335 CodexPlanetEntry::DenseRockyIce => "Dense Rocky Ice Planet",
336 CodexPlanetEntry::DenseRocky => "Dense Rocky Planet",
337
338 CodexPlanetEntry::StandardAmmoniaWorlds => "Standard Ammonia Worlds",
339 CodexPlanetEntry::StandardGiantWithAmmoniaLife =>
340 "Standard Giant with Ammonia Life",
341 CodexPlanetEntry::StandardGiantWithWaterLife => "Standard Giant with Water Life",
342 CodexPlanetEntry::StandardGiants => "Standard Giants",
343 CodexPlanetEntry::StandardHelium => "Standard Helium",
344 CodexPlanetEntry::StandardHeliumRich => "Standard Helium-Rich",
345 CodexPlanetEntry::StandardHighMetalContentNoAtmosphere =>
346 "Standard High Metal Content, No Atmosphere",
347 CodexPlanetEntry::StandardIceNoAtmosphere => "Standard Ice, No Atmosphere",
348 CodexPlanetEntry::StandardMetalRichNoAtmosphere =>
349 "Standard Metal-Rich, No Atmosphere",
350 CodexPlanetEntry::StandardPlanetStandard => "Standard Planet Standard",
351 CodexPlanetEntry::StandardPlanetTerraformable => "Standard Planet Terraformable",
352 CodexPlanetEntry::StandardRockyIceNoAtmosphere =>
353 "Standard Rocky Ice, No Atmosphere",
354 CodexPlanetEntry::StandardRockyNoAtmosphere => "Standard Rocky, No Atmosphere",
355
356 CodexPlanetEntry::StandardSudarskyClassI => "Standard Sudarsky Class I",
357 CodexPlanetEntry::StandardSudarskyClassII => "Standard Sudarsky Class II",
358 CodexPlanetEntry::StandardSudarskyClassIII => "Standard Sudarsky Class III",
359 CodexPlanetEntry::StandardSudarskyClassIV => "Standard Sudarsky Class IV",
360 CodexPlanetEntry::StandardSudarskyClassV => "Standard Sudarsky Class V",
361
362 CodexPlanetEntry::StandardHighMetalContent => "Standard High Metal Content",
363 CodexPlanetEntry::StandardIce => "Standard Ice",
364 CodexPlanetEntry::StandardMetalRich => "Standard Metal-Rich",
365 CodexPlanetEntry::StandardRockyIce => "Standard Rocky Ice",
366 CodexPlanetEntry::StandardRocky => "Standard Rocky",
367
368 CodexPlanetEntry::StandardWaterGiant => "Standard Water Giant",
369 CodexPlanetEntry::StandardWaterGiantWithLife => "Standard Water Giant with Life",
370 CodexPlanetEntry::StandardWaterWorlds => "Standard Water Worlds",
371
372 CodexPlanetEntry::LightAmmoniaWorlds => "Light Ammonia Worlds",
373 CodexPlanetEntry::LightWaterWorlds => "Light Water Worlds",
374 CodexPlanetEntry::LightHighMetalContent => "Light High Metal Content Planet",
375 CodexPlanetEntry::LightIce => "Light Ice Planet",
376 CodexPlanetEntry::LightMetalRich => "Light Metal-Rich Planet",
377 CodexPlanetEntry::LightRockyIce => "Light Rocky Ice Planet",
378 CodexPlanetEntry::LightRocky => "Light Rocky Planet",
379
380 CodexPlanetEntry::GreenGiants => "Green Giants",
381 CodexPlanetEntry::GiantWithAmmoniaLife => "Giant with Ammonia Life",
382 CodexPlanetEntry::GiantWithWaterLife => "Giant with Water Life",
383 CodexPlanetEntry::GreenGiantWithAmmoniaLife => "Green Giant with Ammonia Life",
384 CodexPlanetEntry::GreenGiantWithWaterLife => "Green Giant with Water Life",
385 CodexPlanetEntry::GreenSudarskyClassI => "Green Sudarsky Class I",
386 CodexPlanetEntry::GreenSudarskyClassII => "Green Sudarsky Class II",
387 CodexPlanetEntry::GreenSudarskyClassIII => "Green Sudarsky Class III",
388 CodexPlanetEntry::GreenSudarskyClassIV => "Green Sudarsky Class IV",
389 CodexPlanetEntry::GreenSudarskyClassV => "Green Sudarsky Class V",
390 CodexPlanetEntry::GreenWaterGiant => "Green Water Giant",
391 CodexPlanetEntry::GreenWaterGiantWithLife => "Green Water Giant with Life",
392 CodexPlanetEntry::GreenHelium => "Green Helium Planet",
393 CodexPlanetEntry::GreenHeliumRich => "Green Helium-Rich Planet",
394
395 CodexPlanetEntry::HighMetalContent => "High Metal Content Planet",
396 CodexPlanetEntry::Ice => "Ice Planet",
397 CodexPlanetEntry::MetalRich => "Metal-Rich Planet",
398 CodexPlanetEntry::RockyIce => "Rocky Ice Planet",
399 CodexPlanetEntry::Rocky => "Rocky Planet",
400
401 CodexPlanetEntry::MetalRichNoAtmosphere => "Metal-Rich, No Atmosphere",
402 CodexPlanetEntry::HighMetalContentNoAtmosphere =>
403 "High Metal Content Planet, No Atmosphere",
404 CodexPlanetEntry::IceNoAtmosphere => "Ice Planet, No Atmosphere",
405 CodexPlanetEntry::RockyIceNoAtmosphere => "Rocky Ice Planet, No Atmosphere",
406 CodexPlanetEntry::RockyNoAtmosphere => "Rocky Planet, No Atmosphere",
407
408 CodexPlanetEntry::TerraformableAmmoniaWorlds => "Terraformable Ammonia Worlds",
410 CodexPlanetEntry::TerraformableWaterWorlds => "Terraformable Water Worlds",
411
412 CodexPlanetEntry::TerraformableHighMetalContentNoAtmosphere =>
414 "Terraformable High Metal Content Planet, No Atmosphere",
415 CodexPlanetEntry::TerraformableIceNoAtmosphere =>
416 "Terraformable Ice Planet, No Atmosphere",
417 CodexPlanetEntry::TerraformableMetalRichNoAtmosphere =>
418 "Terraformable Metal-Rich Planet, No Atmosphere",
419 CodexPlanetEntry::TerraformableRockyIceNoAtmosphere =>
420 "Terraformable Rocky Ice Planet, No Atmosphere",
421 CodexPlanetEntry::TerraformableRockyNoAtmosphere =>
422 "Terraformable Rocky Planet, No Atmosphere",
423
424 CodexPlanetEntry::TerraformableHighMetalContent =>
426 "Terraformable High Metal Content Planet",
427 CodexPlanetEntry::TerraformableIce => "Terraformable Ice Planet",
428 CodexPlanetEntry::TerraformableMetalRich => "Terraformable Metal-Rich Planet",
429 CodexPlanetEntry::TerraformableRockyIce => "Terraformable Rocky Ice Planet",
430 CodexPlanetEntry::TerraformableRocky => "Terraformable Rocky Planet",
431
432 #[cfg(feature = "allow-unknown")]
433 CodexPlanetEntry::Unknown(unknown) =>
434 return write!(f, "Unknown planet codex entry: {unknown}"),
435 }
436 )
437 }
438}