1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum TechnetiumIsotope {
6 Tc85,
8 Tc86,
10 Tc87,
12 Tc88,
14 Tc89,
16 Tc90,
18 Tc91,
20 Tc92,
22 Tc93,
24 Tc94,
26 Tc95,
28 Tc96,
30 Tc97,
32 Tc98,
34 Tc99,
36 Tc100,
38 Tc101,
40 Tc102,
42 Tc103,
44 Tc104,
46 Tc105,
48 Tc106,
50 Tc107,
52 Tc108,
54 Tc109,
56 Tc110,
58 Tc111,
60 Tc112,
62 Tc113,
64 Tc114,
66 Tc115,
68 Tc116,
70 Tc117,
72 Tc118,
74 Tc119,
76 Tc120,
78}
79impl super::RelativeAtomicMass for TechnetiumIsotope {
80 #[inline]
81 fn relative_atomic_mass(&self) -> f64 {
82 match self {
83 Self::Tc85 => 84.95058f64,
84 Self::Tc86 => 85.94493f64,
85 Self::Tc87 => 86.9380672f64,
86 Self::Tc88 => 87.93378f64,
87 Self::Tc89 => 88.9276487f64,
88 Self::Tc90 => 89.9240739f64,
89 Self::Tc91 => 90.9184254f64,
90 Self::Tc92 => 91.9152698f64,
91 Self::Tc93 => 92.910246f64,
92 Self::Tc94 => 93.9096536f64,
93 Self::Tc95 => 94.9076536f64,
94 Self::Tc96 => 95.907868f64,
95 Self::Tc97 => 96.9063667f64,
96 Self::Tc98 => 97.9072124f64,
97 Self::Tc99 => 98.9062508f64,
98 Self::Tc100 => 99.9076539f64,
99 Self::Tc101 => 100.907309f64,
100 Self::Tc102 => 101.9092097f64,
101 Self::Tc103 => 102.909176f64,
102 Self::Tc104 => 103.911425f64,
103 Self::Tc105 => 104.911655f64,
104 Self::Tc106 => 105.914358f64,
105 Self::Tc107 => 106.9154606f64,
106 Self::Tc108 => 107.9184957f64,
107 Self::Tc109 => 108.920256f64,
108 Self::Tc110 => 109.923744f64,
109 Self::Tc111 => 110.925901f64,
110 Self::Tc112 => 111.9299458f64,
111 Self::Tc113 => 112.932569f64,
112 Self::Tc114 => 113.93691f64,
113 Self::Tc115 => 114.93998f64,
114 Self::Tc116 => 115.94476f64,
115 Self::Tc117 => 116.94806f64,
116 Self::Tc118 => 117.95299f64,
117 Self::Tc119 => 118.95666f64,
118 Self::Tc120 => 119.96187f64,
119 }
120 }
121}
122impl super::ElementVariant for TechnetiumIsotope {
123 #[inline]
124 fn element(&self) -> crate::Element {
125 crate::Element::Tc
126 }
127}
128impl super::MassNumber for TechnetiumIsotope {
129 #[inline]
130 fn mass_number(&self) -> u16 {
131 match self {
132 Self::Tc85 => 85u16,
133 Self::Tc86 => 86u16,
134 Self::Tc87 => 87u16,
135 Self::Tc88 => 88u16,
136 Self::Tc89 => 89u16,
137 Self::Tc90 => 90u16,
138 Self::Tc91 => 91u16,
139 Self::Tc92 => 92u16,
140 Self::Tc93 => 93u16,
141 Self::Tc94 => 94u16,
142 Self::Tc95 => 95u16,
143 Self::Tc96 => 96u16,
144 Self::Tc97 => 97u16,
145 Self::Tc98 => 98u16,
146 Self::Tc99 => 99u16,
147 Self::Tc100 => 100u16,
148 Self::Tc101 => 101u16,
149 Self::Tc102 => 102u16,
150 Self::Tc103 => 103u16,
151 Self::Tc104 => 104u16,
152 Self::Tc105 => 105u16,
153 Self::Tc106 => 106u16,
154 Self::Tc107 => 107u16,
155 Self::Tc108 => 108u16,
156 Self::Tc109 => 109u16,
157 Self::Tc110 => 110u16,
158 Self::Tc111 => 111u16,
159 Self::Tc112 => 112u16,
160 Self::Tc113 => 113u16,
161 Self::Tc114 => 114u16,
162 Self::Tc115 => 115u16,
163 Self::Tc116 => 116u16,
164 Self::Tc117 => 117u16,
165 Self::Tc118 => 118u16,
166 Self::Tc119 => 119u16,
167 Self::Tc120 => 120u16,
168 }
169 }
170}
171impl super::IsotopicComposition for TechnetiumIsotope {
172 #[inline]
173 fn isotopic_composition(&self) -> Option<f64> {
174 None
175 }
176}
177impl super::MostAbundantIsotope for TechnetiumIsotope {
178 fn most_abundant_isotope() -> Self {
179 Self::Tc120
180 }
181}
182impl From<TechnetiumIsotope> for crate::Isotope {
183 fn from(isotope: TechnetiumIsotope) -> Self {
184 crate::Isotope::Tc(isotope)
185 }
186}
187impl From<TechnetiumIsotope> for crate::Element {
188 fn from(_isotope: TechnetiumIsotope) -> Self {
189 crate::Element::Tc
190 }
191}
192impl TryFrom<u64> for TechnetiumIsotope {
193 type Error = crate::errors::Error;
194 fn try_from(value: u64) -> Result<Self, Self::Error> {
195 match value {
196 85u64 => Ok(Self::Tc85),
197 86u64 => Ok(Self::Tc86),
198 87u64 => Ok(Self::Tc87),
199 88u64 => Ok(Self::Tc88),
200 89u64 => Ok(Self::Tc89),
201 90u64 => Ok(Self::Tc90),
202 91u64 => Ok(Self::Tc91),
203 92u64 => Ok(Self::Tc92),
204 93u64 => Ok(Self::Tc93),
205 94u64 => Ok(Self::Tc94),
206 95u64 => Ok(Self::Tc95),
207 96u64 => Ok(Self::Tc96),
208 97u64 => Ok(Self::Tc97),
209 98u64 => Ok(Self::Tc98),
210 99u64 => Ok(Self::Tc99),
211 100u64 => Ok(Self::Tc100),
212 101u64 => Ok(Self::Tc101),
213 102u64 => Ok(Self::Tc102),
214 103u64 => Ok(Self::Tc103),
215 104u64 => Ok(Self::Tc104),
216 105u64 => Ok(Self::Tc105),
217 106u64 => Ok(Self::Tc106),
218 107u64 => Ok(Self::Tc107),
219 108u64 => Ok(Self::Tc108),
220 109u64 => Ok(Self::Tc109),
221 110u64 => Ok(Self::Tc110),
222 111u64 => Ok(Self::Tc111),
223 112u64 => Ok(Self::Tc112),
224 113u64 => Ok(Self::Tc113),
225 114u64 => Ok(Self::Tc114),
226 115u64 => Ok(Self::Tc115),
227 116u64 => Ok(Self::Tc116),
228 117u64 => Ok(Self::Tc117),
229 118u64 => Ok(Self::Tc118),
230 119u64 => Ok(Self::Tc119),
231 120u64 => Ok(Self::Tc120),
232 _ => Err(crate::errors::Error::Isotope(crate::Element::Tc, value)),
233 }
234 }
235}
236impl TryFrom<u8> for TechnetiumIsotope {
237 type Error = crate::errors::Error;
238 fn try_from(value: u8) -> Result<Self, Self::Error> {
239 Self::try_from(u64::from(value))
240 }
241}
242impl TryFrom<u16> for TechnetiumIsotope {
243 type Error = crate::errors::Error;
244 fn try_from(value: u16) -> Result<Self, Self::Error> {
245 Self::try_from(u64::from(value))
246 }
247}
248impl TryFrom<u32> for TechnetiumIsotope {
249 type Error = crate::errors::Error;
250 fn try_from(value: u32) -> Result<Self, Self::Error> {
251 Self::try_from(u64::from(value))
252 }
253}
254impl core::fmt::Display for TechnetiumIsotope {
255 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
256 match self {
257 Self::Tc85 => write!(f, "Tc85"),
258 Self::Tc86 => write!(f, "Tc86"),
259 Self::Tc87 => write!(f, "Tc87"),
260 Self::Tc88 => write!(f, "Tc88"),
261 Self::Tc89 => write!(f, "Tc89"),
262 Self::Tc90 => write!(f, "Tc90"),
263 Self::Tc91 => write!(f, "Tc91"),
264 Self::Tc92 => write!(f, "Tc92"),
265 Self::Tc93 => write!(f, "Tc93"),
266 Self::Tc94 => write!(f, "Tc94"),
267 Self::Tc95 => write!(f, "Tc95"),
268 Self::Tc96 => write!(f, "Tc96"),
269 Self::Tc97 => write!(f, "Tc97"),
270 Self::Tc98 => write!(f, "Tc98"),
271 Self::Tc99 => write!(f, "Tc99"),
272 Self::Tc100 => write!(f, "Tc100"),
273 Self::Tc101 => write!(f, "Tc101"),
274 Self::Tc102 => write!(f, "Tc102"),
275 Self::Tc103 => write!(f, "Tc103"),
276 Self::Tc104 => write!(f, "Tc104"),
277 Self::Tc105 => write!(f, "Tc105"),
278 Self::Tc106 => write!(f, "Tc106"),
279 Self::Tc107 => write!(f, "Tc107"),
280 Self::Tc108 => write!(f, "Tc108"),
281 Self::Tc109 => write!(f, "Tc109"),
282 Self::Tc110 => write!(f, "Tc110"),
283 Self::Tc111 => write!(f, "Tc111"),
284 Self::Tc112 => write!(f, "Tc112"),
285 Self::Tc113 => write!(f, "Tc113"),
286 Self::Tc114 => write!(f, "Tc114"),
287 Self::Tc115 => write!(f, "Tc115"),
288 Self::Tc116 => write!(f, "Tc116"),
289 Self::Tc117 => write!(f, "Tc117"),
290 Self::Tc118 => write!(f, "Tc118"),
291 Self::Tc119 => write!(f, "Tc119"),
292 Self::Tc120 => write!(f, "Tc120"),
293 }
294 }
295}
296#[cfg(test)]
297mod tests {
298 use strum::IntoEnumIterator;
299
300 use super::*;
301 use crate::isotopes::{
302 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
303 };
304 #[test]
305 fn test_relative_atomic_mass() {
306 for isotope in TechnetiumIsotope::iter() {
307 let mass = isotope.relative_atomic_mass();
308 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
309 }
310 }
311 #[test]
312 fn test_element() {
313 for isotope in TechnetiumIsotope::iter() {
314 let element = isotope.element();
315 assert_eq!(element, crate::Element::Tc, "Element should be correct for {isotope:?}");
316 }
317 }
318 #[test]
319 fn test_mass_number() {
320 for isotope in TechnetiumIsotope::iter() {
321 let mass_number = isotope.mass_number();
322 assert!(
323 mass_number > 0 && mass_number < 300,
324 "Mass number should be reasonable for {isotope:?}"
325 );
326 }
327 }
328 #[test]
329 fn test_isotopic_composition() {
330 for isotope in TechnetiumIsotope::iter() {
331 let comp = isotope.isotopic_composition();
332 if let Some(c) = comp {
333 assert!(
334 (0.0..=1.0).contains(&c),
335 "Composition should be between 0 and 1 for {isotope:?}"
336 );
337 }
338 }
339 }
340 #[test]
341 fn test_most_abundant() {
342 let most_abundant = TechnetiumIsotope::most_abundant_isotope();
343 let _ = most_abundant.relative_atomic_mass();
344 }
345 #[test]
346 fn test_from_isotope() {
347 for isotope in TechnetiumIsotope::iter() {
348 let iso: crate::Isotope = isotope.into();
349 match iso {
350 crate::Isotope::Tc(i) => assert_eq!(i, isotope),
351 _ => panic!("Wrong isotope type"),
352 }
353 }
354 }
355 #[test]
356 fn test_from_element() {
357 for isotope in TechnetiumIsotope::iter() {
358 let elem: crate::Element = isotope.into();
359 assert_eq!(elem, crate::Element::Tc);
360 }
361 }
362 #[test]
363 fn test_try_from_mass_number() {
364 for isotope in TechnetiumIsotope::iter() {
365 let mass = isotope.mass_number();
366 let iso = TechnetiumIsotope::try_from(mass).unwrap();
367 assert_eq!(iso, isotope);
368 let iso_u32 = TechnetiumIsotope::try_from(u32::from(mass)).unwrap();
369 assert_eq!(iso_u32, isotope);
370 if let Ok(mass_u8) = u8::try_from(mass) {
371 let iso_u8 = TechnetiumIsotope::try_from(mass_u8).unwrap();
372 assert_eq!(iso_u8, isotope);
373 }
374 }
375 assert!(TechnetiumIsotope::try_from(0_u16).is_err());
376 assert!(TechnetiumIsotope::try_from(1000_u16).is_err());
377 assert!(TechnetiumIsotope::try_from(0_u32).is_err());
378 assert!(TechnetiumIsotope::try_from(1000_u32).is_err());
379 assert!(TechnetiumIsotope::try_from(0_u8).is_err());
380 }
381 #[test]
382 fn test_display() {
383 for isotope in TechnetiumIsotope::iter() {
384 let s = alloc::format!("{isotope}");
385 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
386 }
387 }
388}