1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum BerylliumIsotope {
6 Be5,
8 Be6,
10 Be7,
12 Be8,
14 Be9,
16 Be10,
18 Be11,
20 Be12,
22 Be13,
24 Be14,
26 Be15,
28 Be16,
30}
31impl super::RelativeAtomicMass for BerylliumIsotope {
32 #[inline]
33 fn relative_atomic_mass(&self) -> f64 {
34 match self {
35 Self::Be5 => 5.0399f64,
36 Self::Be6 => 6.0197264f64,
37 Self::Be7 => 7.016928717f64,
38 Self::Be8 => 8.005305102f64,
39 Self::Be9 => 9.012183065f64,
40 Self::Be10 => 10.013534695f64,
41 Self::Be11 => 11.02166108f64,
42 Self::Be12 => 12.0269221f64,
43 Self::Be13 => 13.036135f64,
44 Self::Be14 => 14.04289f64,
45 Self::Be15 => 15.05342f64,
46 Self::Be16 => 16.06167f64,
47 }
48 }
49}
50impl super::ElementVariant for BerylliumIsotope {
51 #[inline]
52 fn element(&self) -> crate::Element {
53 crate::Element::Be
54 }
55}
56impl super::MassNumber for BerylliumIsotope {
57 #[inline]
58 fn mass_number(&self) -> u16 {
59 match self {
60 Self::Be5 => 5u16,
61 Self::Be6 => 6u16,
62 Self::Be7 => 7u16,
63 Self::Be8 => 8u16,
64 Self::Be9 => 9u16,
65 Self::Be10 => 10u16,
66 Self::Be11 => 11u16,
67 Self::Be12 => 12u16,
68 Self::Be13 => 13u16,
69 Self::Be14 => 14u16,
70 Self::Be15 => 15u16,
71 Self::Be16 => 16u16,
72 }
73 }
74}
75impl super::IsotopicComposition for BerylliumIsotope {
76 #[inline]
77 fn isotopic_composition(&self) -> Option<f64> {
78 match self {
79 Self::Be9 => Some(1f64),
80 _ => None,
81 }
82 }
83}
84impl super::MostAbundantIsotope for BerylliumIsotope {
85 fn most_abundant_isotope() -> Self {
86 Self::Be9
87 }
88}
89impl From<BerylliumIsotope> for crate::Isotope {
90 fn from(isotope: BerylliumIsotope) -> Self {
91 crate::Isotope::Be(isotope)
92 }
93}
94impl From<BerylliumIsotope> for crate::Element {
95 fn from(_isotope: BerylliumIsotope) -> Self {
96 crate::Element::Be
97 }
98}
99impl TryFrom<u64> for BerylliumIsotope {
100 type Error = crate::errors::Error;
101 fn try_from(value: u64) -> Result<Self, Self::Error> {
102 match value {
103 5u64 => Ok(Self::Be5),
104 6u64 => Ok(Self::Be6),
105 7u64 => Ok(Self::Be7),
106 8u64 => Ok(Self::Be8),
107 9u64 => Ok(Self::Be9),
108 10u64 => Ok(Self::Be10),
109 11u64 => Ok(Self::Be11),
110 12u64 => Ok(Self::Be12),
111 13u64 => Ok(Self::Be13),
112 14u64 => Ok(Self::Be14),
113 15u64 => Ok(Self::Be15),
114 16u64 => Ok(Self::Be16),
115 _ => Err(crate::errors::Error::Isotope(crate::Element::Be, value)),
116 }
117 }
118}
119impl TryFrom<u8> for BerylliumIsotope {
120 type Error = crate::errors::Error;
121 fn try_from(value: u8) -> Result<Self, Self::Error> {
122 Self::try_from(u64::from(value))
123 }
124}
125impl TryFrom<u16> for BerylliumIsotope {
126 type Error = crate::errors::Error;
127 fn try_from(value: u16) -> Result<Self, Self::Error> {
128 Self::try_from(u64::from(value))
129 }
130}
131impl TryFrom<u32> for BerylliumIsotope {
132 type Error = crate::errors::Error;
133 fn try_from(value: u32) -> Result<Self, Self::Error> {
134 Self::try_from(u64::from(value))
135 }
136}
137impl core::fmt::Display for BerylliumIsotope {
138 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
139 match self {
140 Self::Be5 => write!(f, "Be5"),
141 Self::Be6 => write!(f, "Be6"),
142 Self::Be7 => write!(f, "Be7"),
143 Self::Be8 => write!(f, "Be8"),
144 Self::Be9 => write!(f, "Be9"),
145 Self::Be10 => write!(f, "Be10"),
146 Self::Be11 => write!(f, "Be11"),
147 Self::Be12 => write!(f, "Be12"),
148 Self::Be13 => write!(f, "Be13"),
149 Self::Be14 => write!(f, "Be14"),
150 Self::Be15 => write!(f, "Be15"),
151 Self::Be16 => write!(f, "Be16"),
152 }
153 }
154}
155#[cfg(test)]
156mod tests {
157 use strum::IntoEnumIterator;
158
159 use super::*;
160 use crate::isotopes::{
161 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
162 };
163 #[test]
164 fn test_relative_atomic_mass() {
165 for isotope in BerylliumIsotope::iter() {
166 let mass = isotope.relative_atomic_mass();
167 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
168 }
169 }
170 #[test]
171 fn test_element() {
172 for isotope in BerylliumIsotope::iter() {
173 let element = isotope.element();
174 assert_eq!(element, crate::Element::Be, "Element should be correct for {isotope:?}");
175 }
176 }
177 #[test]
178 fn test_mass_number() {
179 for isotope in BerylliumIsotope::iter() {
180 let mass_number = isotope.mass_number();
181 assert!(
182 mass_number > 0 && mass_number < 300,
183 "Mass number should be reasonable for {isotope:?}"
184 );
185 }
186 }
187 #[test]
188 fn test_isotopic_composition() {
189 for isotope in BerylliumIsotope::iter() {
190 let comp = isotope.isotopic_composition();
191 if let Some(c) = comp {
192 assert!(
193 (0.0..=1.0).contains(&c),
194 "Composition should be between 0 and 1 for {isotope:?}"
195 );
196 }
197 }
198 }
199 #[test]
200 fn test_most_abundant() {
201 let most_abundant = BerylliumIsotope::most_abundant_isotope();
202 let _ = most_abundant.relative_atomic_mass();
203 }
204 #[test]
205 fn test_from_isotope() {
206 for isotope in BerylliumIsotope::iter() {
207 let iso: crate::Isotope = isotope.into();
208 match iso {
209 crate::Isotope::Be(i) => assert_eq!(i, isotope),
210 _ => panic!("Wrong isotope type"),
211 }
212 }
213 }
214 #[test]
215 fn test_from_element() {
216 for isotope in BerylliumIsotope::iter() {
217 let elem: crate::Element = isotope.into();
218 assert_eq!(elem, crate::Element::Be);
219 }
220 }
221 #[test]
222 fn test_try_from_mass_number() {
223 for isotope in BerylliumIsotope::iter() {
224 let mass = isotope.mass_number();
225 let iso = BerylliumIsotope::try_from(mass).unwrap();
226 assert_eq!(iso, isotope);
227 let iso_u32 = BerylliumIsotope::try_from(u32::from(mass)).unwrap();
228 assert_eq!(iso_u32, isotope);
229 if let Ok(mass_u8) = u8::try_from(mass) {
230 let iso_u8 = BerylliumIsotope::try_from(mass_u8).unwrap();
231 assert_eq!(iso_u8, isotope);
232 }
233 }
234 assert!(BerylliumIsotope::try_from(0_u16).is_err());
235 assert!(BerylliumIsotope::try_from(1000_u16).is_err());
236 assert!(BerylliumIsotope::try_from(0_u32).is_err());
237 assert!(BerylliumIsotope::try_from(1000_u32).is_err());
238 assert!(BerylliumIsotope::try_from(0_u8).is_err());
239 }
240 #[test]
241 fn test_display() {
242 for isotope in BerylliumIsotope::iter() {
243 let s = alloc::format!("{isotope}");
244 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
245 }
246 }
247}