Skip to main content

elements_rs/isotopes/
zinc.rs

1//! Isotopes of the element Zinc
2#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
5/// Isotopes of the element Zinc
6pub enum ZincIsotope {
7    /// Isotope Zn54 of Zinc
8    Zn54,
9    /// Isotope Zn55 of Zinc
10    Zn55,
11    /// Isotope Zn56 of Zinc
12    Zn56,
13    /// Isotope Zn57 of Zinc
14    Zn57,
15    /// Isotope Zn58 of Zinc
16    Zn58,
17    /// Isotope Zn59 of Zinc
18    Zn59,
19    /// Isotope Zn60 of Zinc
20    Zn60,
21    /// Isotope Zn61 of Zinc
22    Zn61,
23    /// Isotope Zn62 of Zinc
24    Zn62,
25    /// Isotope Zn63 of Zinc
26    Zn63,
27    /// Isotope Zn64 of Zinc
28    Zn64,
29    /// Isotope Zn65 of Zinc
30    Zn65,
31    /// Isotope Zn66 of Zinc
32    Zn66,
33    /// Isotope Zn67 of Zinc
34    Zn67,
35    /// Isotope Zn68 of Zinc
36    Zn68,
37    /// Isotope Zn69 of Zinc
38    Zn69,
39    /// Isotope Zn70 of Zinc
40    Zn70,
41    /// Isotope Zn71 of Zinc
42    Zn71,
43    /// Isotope Zn72 of Zinc
44    Zn72,
45    /// Isotope Zn73 of Zinc
46    Zn73,
47    /// Isotope Zn74 of Zinc
48    Zn74,
49    /// Isotope Zn75 of Zinc
50    Zn75,
51    /// Isotope Zn76 of Zinc
52    Zn76,
53    /// Isotope Zn77 of Zinc
54    Zn77,
55    /// Isotope Zn78 of Zinc
56    Zn78,
57    /// Isotope Zn79 of Zinc
58    Zn79,
59    /// Isotope Zn80 of Zinc
60    Zn80,
61    /// Isotope Zn81 of Zinc
62    Zn81,
63    /// Isotope Zn82 of Zinc
64    Zn82,
65    /// Isotope Zn83 of Zinc
66    Zn83,
67    /// Isotope Zn84 of Zinc
68    Zn84,
69    /// Isotope Zn85 of Zinc
70    Zn85,
71}
72impl super::RelativeAtomicMass for ZincIsotope {
73    #[inline]
74    fn relative_atomic_mass(&self) -> f64 {
75        match self {
76            Self::Zn54 => 53.99204f64,
77            Self::Zn55 => 54.98398f64,
78            Self::Zn56 => 55.97254f64,
79            Self::Zn57 => 56.96506f64,
80            Self::Zn58 => 57.954591f64,
81            Self::Zn59 => 58.94931266f64,
82            Self::Zn60 => 59.9418421f64,
83            Self::Zn61 => 60.939507f64,
84            Self::Zn62 => 61.93433397f64,
85            Self::Zn63 => 62.9332115f64,
86            Self::Zn64 => 63.92914201f64,
87            Self::Zn65 => 64.92924077f64,
88            Self::Zn66 => 65.92603381f64,
89            Self::Zn67 => 66.92712775f64,
90            Self::Zn68 => 67.92484455f64,
91            Self::Zn69 => 68.9265507f64,
92            Self::Zn70 => 69.9253192f64,
93            Self::Zn71 => 70.9277196f64,
94            Self::Zn72 => 71.9268428f64,
95            Self::Zn73 => 72.9295826f64,
96            Self::Zn74 => 73.9294073f64,
97            Self::Zn75 => 74.9328402f64,
98            Self::Zn76 => 75.933115f64,
99            Self::Zn77 => 76.9368872f64,
100            Self::Zn78 => 77.9382892f64,
101            Self::Zn79 => 78.9426381f64,
102            Self::Zn80 => 79.9445529f64,
103            Self::Zn81 => 80.9504026f64,
104            Self::Zn82 => 81.95426f64,
105            Self::Zn83 => 82.96056f64,
106            Self::Zn84 => 83.96521f64,
107            Self::Zn85 => 84.97226f64,
108        }
109    }
110}
111impl super::ElementVariant for ZincIsotope {
112    #[inline]
113    fn element(&self) -> crate::Element {
114        crate::Element::Zn
115    }
116}
117impl super::MassNumber for ZincIsotope {
118    #[inline]
119    fn mass_number(&self) -> u16 {
120        match self {
121            Self::Zn54 => 54u16,
122            Self::Zn55 => 55u16,
123            Self::Zn56 => 56u16,
124            Self::Zn57 => 57u16,
125            Self::Zn58 => 58u16,
126            Self::Zn59 => 59u16,
127            Self::Zn60 => 60u16,
128            Self::Zn61 => 61u16,
129            Self::Zn62 => 62u16,
130            Self::Zn63 => 63u16,
131            Self::Zn64 => 64u16,
132            Self::Zn65 => 65u16,
133            Self::Zn66 => 66u16,
134            Self::Zn67 => 67u16,
135            Self::Zn68 => 68u16,
136            Self::Zn69 => 69u16,
137            Self::Zn70 => 70u16,
138            Self::Zn71 => 71u16,
139            Self::Zn72 => 72u16,
140            Self::Zn73 => 73u16,
141            Self::Zn74 => 74u16,
142            Self::Zn75 => 75u16,
143            Self::Zn76 => 76u16,
144            Self::Zn77 => 77u16,
145            Self::Zn78 => 78u16,
146            Self::Zn79 => 79u16,
147            Self::Zn80 => 80u16,
148            Self::Zn81 => 81u16,
149            Self::Zn82 => 82u16,
150            Self::Zn83 => 83u16,
151            Self::Zn84 => 84u16,
152            Self::Zn85 => 85u16,
153        }
154    }
155}
156impl super::IsotopicComposition for ZincIsotope {
157    #[inline]
158    fn isotopic_composition(&self) -> Option<f64> {
159        match self {
160            Self::Zn64 => Some(0.4917f64),
161            Self::Zn66 => Some(0.2773f64),
162            Self::Zn67 => Some(0.0404f64),
163            Self::Zn68 => Some(0.1845f64),
164            Self::Zn70 => Some(0.0061f64),
165            _ => None,
166        }
167    }
168}
169impl super::MostAbundantIsotope for ZincIsotope {
170    fn most_abundant_isotope() -> Self {
171        Self::Zn64
172    }
173}
174impl From<ZincIsotope> for crate::Isotope {
175    fn from(isotope: ZincIsotope) -> Self {
176        crate::Isotope::Zn(isotope)
177    }
178}
179impl From<ZincIsotope> for crate::Element {
180    fn from(_isotope: ZincIsotope) -> Self {
181        crate::Element::Zn
182    }
183}
184impl TryFrom<u64> for ZincIsotope {
185    type Error = crate::errors::Error;
186    fn try_from(value: u64) -> Result<Self, Self::Error> {
187        match value {
188            54u64 => Ok(Self::Zn54),
189            55u64 => Ok(Self::Zn55),
190            56u64 => Ok(Self::Zn56),
191            57u64 => Ok(Self::Zn57),
192            58u64 => Ok(Self::Zn58),
193            59u64 => Ok(Self::Zn59),
194            60u64 => Ok(Self::Zn60),
195            61u64 => Ok(Self::Zn61),
196            62u64 => Ok(Self::Zn62),
197            63u64 => Ok(Self::Zn63),
198            64u64 => Ok(Self::Zn64),
199            65u64 => Ok(Self::Zn65),
200            66u64 => Ok(Self::Zn66),
201            67u64 => Ok(Self::Zn67),
202            68u64 => Ok(Self::Zn68),
203            69u64 => Ok(Self::Zn69),
204            70u64 => Ok(Self::Zn70),
205            71u64 => Ok(Self::Zn71),
206            72u64 => Ok(Self::Zn72),
207            73u64 => Ok(Self::Zn73),
208            74u64 => Ok(Self::Zn74),
209            75u64 => Ok(Self::Zn75),
210            76u64 => Ok(Self::Zn76),
211            77u64 => Ok(Self::Zn77),
212            78u64 => Ok(Self::Zn78),
213            79u64 => Ok(Self::Zn79),
214            80u64 => Ok(Self::Zn80),
215            81u64 => Ok(Self::Zn81),
216            82u64 => Ok(Self::Zn82),
217            83u64 => Ok(Self::Zn83),
218            84u64 => Ok(Self::Zn84),
219            85u64 => Ok(Self::Zn85),
220            _ => Err(crate::errors::Error::Isotope(crate::Element::Zn, value)),
221        }
222    }
223}
224impl TryFrom<u8> for ZincIsotope {
225    type Error = crate::errors::Error;
226    fn try_from(value: u8) -> Result<Self, Self::Error> {
227        Self::try_from(u64::from(value))
228    }
229}
230impl TryFrom<u16> for ZincIsotope {
231    type Error = crate::errors::Error;
232    fn try_from(value: u16) -> Result<Self, Self::Error> {
233        Self::try_from(u64::from(value))
234    }
235}
236impl TryFrom<u32> for ZincIsotope {
237    type Error = crate::errors::Error;
238    fn try_from(value: u32) -> Result<Self, Self::Error> {
239        Self::try_from(u64::from(value))
240    }
241}
242impl core::fmt::Display for ZincIsotope {
243    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
244        match self {
245            Self::Zn54 => write!(f, "Zn54"),
246            Self::Zn55 => write!(f, "Zn55"),
247            Self::Zn56 => write!(f, "Zn56"),
248            Self::Zn57 => write!(f, "Zn57"),
249            Self::Zn58 => write!(f, "Zn58"),
250            Self::Zn59 => write!(f, "Zn59"),
251            Self::Zn60 => write!(f, "Zn60"),
252            Self::Zn61 => write!(f, "Zn61"),
253            Self::Zn62 => write!(f, "Zn62"),
254            Self::Zn63 => write!(f, "Zn63"),
255            Self::Zn64 => write!(f, "Zn64"),
256            Self::Zn65 => write!(f, "Zn65"),
257            Self::Zn66 => write!(f, "Zn66"),
258            Self::Zn67 => write!(f, "Zn67"),
259            Self::Zn68 => write!(f, "Zn68"),
260            Self::Zn69 => write!(f, "Zn69"),
261            Self::Zn70 => write!(f, "Zn70"),
262            Self::Zn71 => write!(f, "Zn71"),
263            Self::Zn72 => write!(f, "Zn72"),
264            Self::Zn73 => write!(f, "Zn73"),
265            Self::Zn74 => write!(f, "Zn74"),
266            Self::Zn75 => write!(f, "Zn75"),
267            Self::Zn76 => write!(f, "Zn76"),
268            Self::Zn77 => write!(f, "Zn77"),
269            Self::Zn78 => write!(f, "Zn78"),
270            Self::Zn79 => write!(f, "Zn79"),
271            Self::Zn80 => write!(f, "Zn80"),
272            Self::Zn81 => write!(f, "Zn81"),
273            Self::Zn82 => write!(f, "Zn82"),
274            Self::Zn83 => write!(f, "Zn83"),
275            Self::Zn84 => write!(f, "Zn84"),
276            Self::Zn85 => write!(f, "Zn85"),
277        }
278    }
279}
280#[cfg(test)]
281mod tests {
282    use strum::IntoEnumIterator;
283
284    use super::*;
285    use crate::isotopes::{
286        ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
287    };
288    #[test]
289    fn test_relative_atomic_mass() {
290        for isotope in ZincIsotope::iter() {
291            let mass = isotope.relative_atomic_mass();
292            assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
293        }
294    }
295    #[test]
296    fn test_element() {
297        for isotope in ZincIsotope::iter() {
298            let element = isotope.element();
299            assert_eq!(element, crate::Element::Zn, "Element should be correct for {isotope:?}");
300        }
301    }
302    #[test]
303    fn test_mass_number() {
304        for isotope in ZincIsotope::iter() {
305            let mass_number = isotope.mass_number();
306            assert!(
307                mass_number > 0 && mass_number < 300,
308                "Mass number should be reasonable for {isotope:?}"
309            );
310        }
311    }
312    #[test]
313    fn test_isotopic_composition() {
314        for isotope in ZincIsotope::iter() {
315            let comp = isotope.isotopic_composition();
316            if let Some(c) = comp {
317                assert!(
318                    (0.0..=1.0).contains(&c),
319                    "Composition should be between 0 and 1 for {isotope:?}"
320                );
321            }
322        }
323    }
324    #[test]
325    fn test_most_abundant() {
326        let most_abundant = ZincIsotope::most_abundant_isotope();
327        let _ = most_abundant.relative_atomic_mass();
328    }
329    #[test]
330    fn test_from_isotope() {
331        for isotope in ZincIsotope::iter() {
332            let iso: crate::Isotope = isotope.into();
333            match iso {
334                crate::Isotope::Zn(i) => assert_eq!(i, isotope),
335                _ => panic!("Wrong isotope type"),
336            }
337        }
338    }
339    #[test]
340    fn test_from_element() {
341        for isotope in ZincIsotope::iter() {
342            let elem: crate::Element = isotope.into();
343            assert_eq!(elem, crate::Element::Zn);
344        }
345    }
346    #[test]
347    fn test_try_from_mass_number() {
348        for isotope in ZincIsotope::iter() {
349            let mass = isotope.mass_number();
350            let iso = ZincIsotope::try_from(mass).unwrap();
351            assert_eq!(iso, isotope);
352            let iso_u32 = ZincIsotope::try_from(u32::from(mass)).unwrap();
353            assert_eq!(iso_u32, isotope);
354            if let Ok(mass_u8) = u8::try_from(mass) {
355                let iso_u8 = ZincIsotope::try_from(mass_u8).unwrap();
356                assert_eq!(iso_u8, isotope);
357            }
358        }
359        assert!(ZincIsotope::try_from(0_u16).is_err());
360        assert!(ZincIsotope::try_from(1000_u16).is_err());
361        assert!(ZincIsotope::try_from(0_u32).is_err());
362        assert!(ZincIsotope::try_from(1000_u32).is_err());
363        assert!(ZincIsotope::try_from(0_u8).is_err());
364    }
365    #[test]
366    fn test_display() {
367        for isotope in ZincIsotope::iter() {
368            let s = alloc::format!("{isotope}");
369            assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
370        }
371    }
372}