chemistru_elements/
misc.rs

1use strum_macros::IntoStaticStr;
2
3#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
4pub struct MiscData {
5    pub(crate) appearance: Option<&'static str>,
6    pub(crate) category: Category,
7    pub(crate) discovered_by: Option<&'static str>,
8    pub(crate) named_by: Option<&'static str>,
9    pub(crate) spectral_img: Option<&'static str>,
10    pub(crate) source: &'static str,
11    pub(crate) summary: String,
12    pub(crate) cpk_color: Option<&'static str>,
13}
14
15impl MiscData {
16    #[must_use]
17    pub const fn appearance(&self) -> Option<&'static str> {
18        self.appearance
19    }
20
21    #[must_use]
22    pub const fn category(&self) -> &Category {
23        &self.category
24    }
25
26    #[must_use]
27    pub const fn discovered_by(&self) -> Option<&'static str> {
28        self.discovered_by
29    }
30
31    #[must_use]
32    pub const fn named_by(&self) -> Option<&'static str> {
33        self.named_by
34    }
35
36    #[must_use]
37    pub const fn spectral_image_url(&self) -> Option<&'static str> {
38        self.spectral_img
39    }
40
41    #[must_use]
42    pub const fn source(&self) -> &'static str {
43        self.source
44    }
45
46    #[must_use]
47    pub fn summary(&self) -> &str {
48        &self.summary
49    }
50
51    #[must_use]
52    pub const fn cpk_color(&self) -> Option<&'static str> {
53        self.cpk_color
54    }
55
56    #[allow(clippy::too_many_arguments)]
57    #[must_use]
58    pub const fn new(
59        appearance: Option<&'static str>,
60        category: Category,
61        discovered_by: Option<&'static str>,
62        named_by: Option<&'static str>,
63        spectral_img: Option<&'static str>,
64        source: &'static str,
65        summary: String,
66        cpk_color: Option<&'static str>,
67    ) -> Self {
68        Self {
69            appearance,
70            category,
71            discovered_by,
72            named_by,
73            spectral_img,
74            source,
75            summary,
76            cpk_color,
77        }
78    }
79}
80
81#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IntoStaticStr)]
82pub enum Category {
83    DiatomicNonmetal,
84    NobleGas,
85    AlkaliMetal,
86    AlkalineEarthMetal,
87    Metalloid,
88    PolyatomicNonmetal,
89    PostTransitionMetal,
90    TransitionMetal,
91    Lanthanide,
92    Actinide,
93    Unknown { predicted: Box<Category> },
94}
95
96impl From<&str> for Category {
97    fn from(value: &str) -> Self {
98        match value {
99            "diatomic nonmetal" => Self::DiatomicNonmetal,
100            "noble gas" => Self::NobleGas,
101            "alkali metal" => Self::AlkaliMetal,
102            "alkaline earth metal" => Self::AlkalineEarthMetal,
103            "metalloid" => Self::Metalloid,
104            "polyatomic nonmetal" => Self::PolyatomicNonmetal,
105            "post-transition metal" => Self::PostTransitionMetal,
106            "transition metal" => Self::TransitionMetal,
107            "lanthanide" => Self::Lanthanide,
108            "actinide" => Self::Actinide,
109            s => {
110                if s.starts_with("unknown") {
111                    let inner = if s.contains("diatomic nonmetal") {
112                        Self::DiatomicNonmetal
113                    } else if s.contains("noble gas") {
114                        Self::NobleGas
115                    } else if s.contains("alkali metal") {
116                        Self::AlkaliMetal
117                    } else if s.contains("alkaline earth metal") {
118                        Self::AlkalineEarthMetal
119                    } else if s.contains("metalloid") {
120                        Self::Metalloid
121                    } else if s.contains("polyatomic nonmetal") {
122                        Self::PolyatomicNonmetal
123                    } else if s.contains("post-transition metal") {
124                        Self::PostTransitionMetal
125                    } else if s.contains("transition metal") {
126                        Self::TransitionMetal
127                    } else if s.contains("lanthanide") {
128                        Self::Lanthanide
129                    } else if s.contains("actinide") {
130                        Self::Actinide
131                    } else {
132                        panic!("Unrecognised element category '{s}'");
133                    };
134
135                    Self::Unknown {
136                        predicted: Box::new(inner),
137                    }
138                } else {
139                    panic!("Unrecognised element category '{s}'")
140                }
141            }
142        }
143    }
144}