1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum BromineIsotope {
6 Br67,
8 Br68,
10 Br69,
12 Br70,
14 Br71,
16 Br72,
18 Br73,
20 Br74,
22 Br75,
24 Br76,
26 Br77,
28 Br78,
30 Br79,
32 Br80,
34 Br81,
36 Br82,
38 Br83,
40 Br84,
42 Br85,
44 Br86,
46 Br87,
48 Br88,
50 Br89,
52 Br90,
54 Br91,
56 Br92,
58 Br93,
60 Br94,
62 Br95,
64 Br96,
66 Br97,
68 Br98,
70}
71impl super::RelativeAtomicMass for BromineIsotope {
72 #[inline]
73 fn relative_atomic_mass(&self) -> f64 {
74 match self {
75 Self::Br67 => 66.96465f64,
76 Self::Br68 => 67.95873f64,
77 Self::Br69 => 68.950497f64,
78 Self::Br70 => 69.944792f64,
79 Self::Br71 => 70.9393422f64,
80 Self::Br72 => 71.9365886f64,
81 Self::Br73 => 72.9316715f64,
82 Self::Br74 => 73.9299102f64,
83 Self::Br75 => 74.9258105f64,
84 Self::Br76 => 75.924542f64,
85 Self::Br77 => 76.9213792f64,
86 Self::Br78 => 77.9211459f64,
87 Self::Br79 => 78.9183376f64,
88 Self::Br80 => 79.9185298f64,
89 Self::Br81 => 80.9162897f64,
90 Self::Br82 => 81.9168032f64,
91 Self::Br83 => 82.9151756f64,
92 Self::Br84 => 83.916496f64,
93 Self::Br85 => 84.9156458f64,
94 Self::Br86 => 85.9188054f64,
95 Self::Br87 => 86.920674f64,
96 Self::Br88 => 87.9240833f64,
97 Self::Br89 => 88.9267046f64,
98 Self::Br90 => 89.9312928f64,
99 Self::Br91 => 90.9343986f64,
100 Self::Br92 => 91.9396316f64,
101 Self::Br93 => 92.94313f64,
102 Self::Br94 => 93.9489f64,
103 Self::Br95 => 94.95301f64,
104 Self::Br96 => 95.95903f64,
105 Self::Br97 => 96.96344f64,
106 Self::Br98 => 97.96946f64,
107 }
108 }
109}
110impl super::ElementVariant for BromineIsotope {
111 #[inline]
112 fn element(&self) -> crate::Element {
113 crate::Element::Br
114 }
115}
116impl super::MassNumber for BromineIsotope {
117 #[inline]
118 fn mass_number(&self) -> u16 {
119 match self {
120 Self::Br67 => 67u16,
121 Self::Br68 => 68u16,
122 Self::Br69 => 69u16,
123 Self::Br70 => 70u16,
124 Self::Br71 => 71u16,
125 Self::Br72 => 72u16,
126 Self::Br73 => 73u16,
127 Self::Br74 => 74u16,
128 Self::Br75 => 75u16,
129 Self::Br76 => 76u16,
130 Self::Br77 => 77u16,
131 Self::Br78 => 78u16,
132 Self::Br79 => 79u16,
133 Self::Br80 => 80u16,
134 Self::Br81 => 81u16,
135 Self::Br82 => 82u16,
136 Self::Br83 => 83u16,
137 Self::Br84 => 84u16,
138 Self::Br85 => 85u16,
139 Self::Br86 => 86u16,
140 Self::Br87 => 87u16,
141 Self::Br88 => 88u16,
142 Self::Br89 => 89u16,
143 Self::Br90 => 90u16,
144 Self::Br91 => 91u16,
145 Self::Br92 => 92u16,
146 Self::Br93 => 93u16,
147 Self::Br94 => 94u16,
148 Self::Br95 => 95u16,
149 Self::Br96 => 96u16,
150 Self::Br97 => 97u16,
151 Self::Br98 => 98u16,
152 }
153 }
154}
155impl super::IsotopicComposition for BromineIsotope {
156 #[inline]
157 fn isotopic_composition(&self) -> Option<f64> {
158 match self {
159 Self::Br79 => Some(0.5069f64),
160 Self::Br81 => Some(0.4931f64),
161 _ => None,
162 }
163 }
164}
165impl super::MostAbundantIsotope for BromineIsotope {
166 fn most_abundant_isotope() -> Self {
167 Self::Br79
168 }
169}
170impl From<BromineIsotope> for crate::Isotope {
171 fn from(isotope: BromineIsotope) -> Self {
172 crate::Isotope::Br(isotope)
173 }
174}
175impl From<BromineIsotope> for crate::Element {
176 fn from(_isotope: BromineIsotope) -> Self {
177 crate::Element::Br
178 }
179}
180impl TryFrom<u64> for BromineIsotope {
181 type Error = crate::errors::Error;
182 fn try_from(value: u64) -> Result<Self, Self::Error> {
183 match value {
184 67u64 => Ok(Self::Br67),
185 68u64 => Ok(Self::Br68),
186 69u64 => Ok(Self::Br69),
187 70u64 => Ok(Self::Br70),
188 71u64 => Ok(Self::Br71),
189 72u64 => Ok(Self::Br72),
190 73u64 => Ok(Self::Br73),
191 74u64 => Ok(Self::Br74),
192 75u64 => Ok(Self::Br75),
193 76u64 => Ok(Self::Br76),
194 77u64 => Ok(Self::Br77),
195 78u64 => Ok(Self::Br78),
196 79u64 => Ok(Self::Br79),
197 80u64 => Ok(Self::Br80),
198 81u64 => Ok(Self::Br81),
199 82u64 => Ok(Self::Br82),
200 83u64 => Ok(Self::Br83),
201 84u64 => Ok(Self::Br84),
202 85u64 => Ok(Self::Br85),
203 86u64 => Ok(Self::Br86),
204 87u64 => Ok(Self::Br87),
205 88u64 => Ok(Self::Br88),
206 89u64 => Ok(Self::Br89),
207 90u64 => Ok(Self::Br90),
208 91u64 => Ok(Self::Br91),
209 92u64 => Ok(Self::Br92),
210 93u64 => Ok(Self::Br93),
211 94u64 => Ok(Self::Br94),
212 95u64 => Ok(Self::Br95),
213 96u64 => Ok(Self::Br96),
214 97u64 => Ok(Self::Br97),
215 98u64 => Ok(Self::Br98),
216 _ => Err(crate::errors::Error::Isotope(crate::Element::Br, value)),
217 }
218 }
219}
220impl TryFrom<u8> for BromineIsotope {
221 type Error = crate::errors::Error;
222 fn try_from(value: u8) -> Result<Self, Self::Error> {
223 Self::try_from(u64::from(value))
224 }
225}
226impl TryFrom<u16> for BromineIsotope {
227 type Error = crate::errors::Error;
228 fn try_from(value: u16) -> Result<Self, Self::Error> {
229 Self::try_from(u64::from(value))
230 }
231}
232impl TryFrom<u32> for BromineIsotope {
233 type Error = crate::errors::Error;
234 fn try_from(value: u32) -> Result<Self, Self::Error> {
235 Self::try_from(u64::from(value))
236 }
237}
238impl core::fmt::Display for BromineIsotope {
239 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
240 match self {
241 Self::Br67 => write!(f, "Br67"),
242 Self::Br68 => write!(f, "Br68"),
243 Self::Br69 => write!(f, "Br69"),
244 Self::Br70 => write!(f, "Br70"),
245 Self::Br71 => write!(f, "Br71"),
246 Self::Br72 => write!(f, "Br72"),
247 Self::Br73 => write!(f, "Br73"),
248 Self::Br74 => write!(f, "Br74"),
249 Self::Br75 => write!(f, "Br75"),
250 Self::Br76 => write!(f, "Br76"),
251 Self::Br77 => write!(f, "Br77"),
252 Self::Br78 => write!(f, "Br78"),
253 Self::Br79 => write!(f, "Br79"),
254 Self::Br80 => write!(f, "Br80"),
255 Self::Br81 => write!(f, "Br81"),
256 Self::Br82 => write!(f, "Br82"),
257 Self::Br83 => write!(f, "Br83"),
258 Self::Br84 => write!(f, "Br84"),
259 Self::Br85 => write!(f, "Br85"),
260 Self::Br86 => write!(f, "Br86"),
261 Self::Br87 => write!(f, "Br87"),
262 Self::Br88 => write!(f, "Br88"),
263 Self::Br89 => write!(f, "Br89"),
264 Self::Br90 => write!(f, "Br90"),
265 Self::Br91 => write!(f, "Br91"),
266 Self::Br92 => write!(f, "Br92"),
267 Self::Br93 => write!(f, "Br93"),
268 Self::Br94 => write!(f, "Br94"),
269 Self::Br95 => write!(f, "Br95"),
270 Self::Br96 => write!(f, "Br96"),
271 Self::Br97 => write!(f, "Br97"),
272 Self::Br98 => write!(f, "Br98"),
273 }
274 }
275}
276#[cfg(test)]
277mod tests {
278 use strum::IntoEnumIterator;
279
280 use super::*;
281 use crate::isotopes::{
282 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
283 };
284 #[test]
285 fn test_relative_atomic_mass() {
286 for isotope in BromineIsotope::iter() {
287 let mass = isotope.relative_atomic_mass();
288 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
289 }
290 }
291 #[test]
292 fn test_element() {
293 for isotope in BromineIsotope::iter() {
294 let element = isotope.element();
295 assert_eq!(element, crate::Element::Br, "Element should be correct for {isotope:?}");
296 }
297 }
298 #[test]
299 fn test_mass_number() {
300 for isotope in BromineIsotope::iter() {
301 let mass_number = isotope.mass_number();
302 assert!(
303 mass_number > 0 && mass_number < 300,
304 "Mass number should be reasonable for {isotope:?}"
305 );
306 }
307 }
308 #[test]
309 fn test_isotopic_composition() {
310 for isotope in BromineIsotope::iter() {
311 let comp = isotope.isotopic_composition();
312 if let Some(c) = comp {
313 assert!(
314 (0.0..=1.0).contains(&c),
315 "Composition should be between 0 and 1 for {isotope:?}"
316 );
317 }
318 }
319 }
320 #[test]
321 fn test_most_abundant() {
322 let most_abundant = BromineIsotope::most_abundant_isotope();
323 let _ = most_abundant.relative_atomic_mass();
324 }
325 #[test]
326 fn test_from_isotope() {
327 for isotope in BromineIsotope::iter() {
328 let iso: crate::Isotope = isotope.into();
329 match iso {
330 crate::Isotope::Br(i) => assert_eq!(i, isotope),
331 _ => panic!("Wrong isotope type"),
332 }
333 }
334 }
335 #[test]
336 fn test_from_element() {
337 for isotope in BromineIsotope::iter() {
338 let elem: crate::Element = isotope.into();
339 assert_eq!(elem, crate::Element::Br);
340 }
341 }
342 #[test]
343 fn test_try_from_mass_number() {
344 for isotope in BromineIsotope::iter() {
345 let mass = isotope.mass_number();
346 let iso = BromineIsotope::try_from(mass).unwrap();
347 assert_eq!(iso, isotope);
348 let iso_u32 = BromineIsotope::try_from(u32::from(mass)).unwrap();
349 assert_eq!(iso_u32, isotope);
350 if let Ok(mass_u8) = u8::try_from(mass) {
351 let iso_u8 = BromineIsotope::try_from(mass_u8).unwrap();
352 assert_eq!(iso_u8, isotope);
353 }
354 }
355 assert!(BromineIsotope::try_from(0_u16).is_err());
356 assert!(BromineIsotope::try_from(1000_u16).is_err());
357 assert!(BromineIsotope::try_from(0_u32).is_err());
358 assert!(BromineIsotope::try_from(1000_u32).is_err());
359 assert!(BromineIsotope::try_from(0_u8).is_err());
360 }
361 #[test]
362 fn test_display() {
363 for isotope in BromineIsotope::iter() {
364 let s = alloc::format!("{isotope}");
365 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
366 }
367 }
368}