1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum BismuthIsotope {
6 Bi184,
8 Bi185,
10 Bi186,
12 Bi187,
14 Bi188,
16 Bi189,
18 Bi190,
20 Bi191,
22 Bi192,
24 Bi193,
26 Bi194,
28 Bi195,
30 Bi196,
32 Bi197,
34 Bi198,
36 Bi199,
38 Bi200,
40 Bi201,
42 Bi202,
44 Bi203,
46 Bi204,
48 Bi205,
50 Bi206,
52 Bi207,
54 Bi208,
56 Bi209,
58 Bi210,
60 Bi211,
62 Bi212,
64 Bi213,
66 Bi214,
68 Bi215,
70 Bi216,
72 Bi217,
74 Bi218,
76 Bi219,
78 Bi220,
80 Bi221,
82 Bi222,
84 Bi223,
86 Bi224,
88}
89impl super::RelativeAtomicMass for BismuthIsotope {
90 #[inline]
91 fn relative_atomic_mass(&self) -> f64 {
92 match self {
93 Self::Bi184 => 184.001275f64,
94 Self::Bi185 => 184.9976f64,
95 Self::Bi186 => 185.996644f64,
96 Self::Bi187 => 186.993147f64,
97 Self::Bi188 => 187.992287f64,
98 Self::Bi189 => 188.989195f64,
99 Self::Bi190 => 189.988622f64,
100 Self::Bi191 => 190.9857866f64,
101 Self::Bi192 => 191.985469f64,
102 Self::Bi193 => 192.98296f64,
103 Self::Bi194 => 193.982785f64,
104 Self::Bi195 => 194.9806488f64,
105 Self::Bi196 => 195.980667f64,
106 Self::Bi197 => 196.9788651f64,
107 Self::Bi198 => 197.979206f64,
108 Self::Bi199 => 198.977673f64,
109 Self::Bi200 => 199.978131f64,
110 Self::Bi201 => 200.97701f64,
111 Self::Bi202 => 201.977734f64,
112 Self::Bi203 => 202.976893f64,
113 Self::Bi204 => 203.9778361f64,
114 Self::Bi205 => 204.9773867f64,
115 Self::Bi206 => 205.9784993f64,
116 Self::Bi207 => 206.978471f64,
117 Self::Bi208 => 207.9797425f64,
118 Self::Bi209 => 208.9803991f64,
119 Self::Bi210 => 209.9841207f64,
120 Self::Bi211 => 210.9872697f64,
121 Self::Bi212 => 211.991286f64,
122 Self::Bi213 => 212.9943851f64,
123 Self::Bi214 => 213.998712f64,
124 Self::Bi215 => 215.00177f64,
125 Self::Bi216 => 216.006306f64,
126 Self::Bi217 => 217.009372f64,
127 Self::Bi218 => 218.014188f64,
128 Self::Bi219 => 219.01748f64,
129 Self::Bi220 => 220.02235f64,
130 Self::Bi221 => 221.02587f64,
131 Self::Bi222 => 222.03078f64,
132 Self::Bi223 => 223.0345f64,
133 Self::Bi224 => 224.03947f64,
134 }
135 }
136}
137impl super::ElementVariant for BismuthIsotope {
138 #[inline]
139 fn element(&self) -> crate::Element {
140 crate::Element::Bi
141 }
142}
143impl super::MassNumber for BismuthIsotope {
144 #[inline]
145 fn mass_number(&self) -> u16 {
146 match self {
147 Self::Bi184 => 184u16,
148 Self::Bi185 => 185u16,
149 Self::Bi186 => 186u16,
150 Self::Bi187 => 187u16,
151 Self::Bi188 => 188u16,
152 Self::Bi189 => 189u16,
153 Self::Bi190 => 190u16,
154 Self::Bi191 => 191u16,
155 Self::Bi192 => 192u16,
156 Self::Bi193 => 193u16,
157 Self::Bi194 => 194u16,
158 Self::Bi195 => 195u16,
159 Self::Bi196 => 196u16,
160 Self::Bi197 => 197u16,
161 Self::Bi198 => 198u16,
162 Self::Bi199 => 199u16,
163 Self::Bi200 => 200u16,
164 Self::Bi201 => 201u16,
165 Self::Bi202 => 202u16,
166 Self::Bi203 => 203u16,
167 Self::Bi204 => 204u16,
168 Self::Bi205 => 205u16,
169 Self::Bi206 => 206u16,
170 Self::Bi207 => 207u16,
171 Self::Bi208 => 208u16,
172 Self::Bi209 => 209u16,
173 Self::Bi210 => 210u16,
174 Self::Bi211 => 211u16,
175 Self::Bi212 => 212u16,
176 Self::Bi213 => 213u16,
177 Self::Bi214 => 214u16,
178 Self::Bi215 => 215u16,
179 Self::Bi216 => 216u16,
180 Self::Bi217 => 217u16,
181 Self::Bi218 => 218u16,
182 Self::Bi219 => 219u16,
183 Self::Bi220 => 220u16,
184 Self::Bi221 => 221u16,
185 Self::Bi222 => 222u16,
186 Self::Bi223 => 223u16,
187 Self::Bi224 => 224u16,
188 }
189 }
190}
191impl super::IsotopicComposition for BismuthIsotope {
192 #[inline]
193 fn isotopic_composition(&self) -> Option<f64> {
194 match self {
195 Self::Bi209 => Some(1f64),
196 _ => None,
197 }
198 }
199}
200impl super::MostAbundantIsotope for BismuthIsotope {
201 fn most_abundant_isotope() -> Self {
202 Self::Bi209
203 }
204}
205impl From<BismuthIsotope> for crate::Isotope {
206 fn from(isotope: BismuthIsotope) -> Self {
207 crate::Isotope::Bi(isotope)
208 }
209}
210impl From<BismuthIsotope> for crate::Element {
211 fn from(_isotope: BismuthIsotope) -> Self {
212 crate::Element::Bi
213 }
214}
215impl TryFrom<u64> for BismuthIsotope {
216 type Error = crate::errors::Error;
217 fn try_from(value: u64) -> Result<Self, Self::Error> {
218 match value {
219 184u64 => Ok(Self::Bi184),
220 185u64 => Ok(Self::Bi185),
221 186u64 => Ok(Self::Bi186),
222 187u64 => Ok(Self::Bi187),
223 188u64 => Ok(Self::Bi188),
224 189u64 => Ok(Self::Bi189),
225 190u64 => Ok(Self::Bi190),
226 191u64 => Ok(Self::Bi191),
227 192u64 => Ok(Self::Bi192),
228 193u64 => Ok(Self::Bi193),
229 194u64 => Ok(Self::Bi194),
230 195u64 => Ok(Self::Bi195),
231 196u64 => Ok(Self::Bi196),
232 197u64 => Ok(Self::Bi197),
233 198u64 => Ok(Self::Bi198),
234 199u64 => Ok(Self::Bi199),
235 200u64 => Ok(Self::Bi200),
236 201u64 => Ok(Self::Bi201),
237 202u64 => Ok(Self::Bi202),
238 203u64 => Ok(Self::Bi203),
239 204u64 => Ok(Self::Bi204),
240 205u64 => Ok(Self::Bi205),
241 206u64 => Ok(Self::Bi206),
242 207u64 => Ok(Self::Bi207),
243 208u64 => Ok(Self::Bi208),
244 209u64 => Ok(Self::Bi209),
245 210u64 => Ok(Self::Bi210),
246 211u64 => Ok(Self::Bi211),
247 212u64 => Ok(Self::Bi212),
248 213u64 => Ok(Self::Bi213),
249 214u64 => Ok(Self::Bi214),
250 215u64 => Ok(Self::Bi215),
251 216u64 => Ok(Self::Bi216),
252 217u64 => Ok(Self::Bi217),
253 218u64 => Ok(Self::Bi218),
254 219u64 => Ok(Self::Bi219),
255 220u64 => Ok(Self::Bi220),
256 221u64 => Ok(Self::Bi221),
257 222u64 => Ok(Self::Bi222),
258 223u64 => Ok(Self::Bi223),
259 224u64 => Ok(Self::Bi224),
260 _ => Err(crate::errors::Error::Isotope(crate::Element::Bi, value)),
261 }
262 }
263}
264impl TryFrom<u8> for BismuthIsotope {
265 type Error = crate::errors::Error;
266 fn try_from(value: u8) -> Result<Self, Self::Error> {
267 Self::try_from(u64::from(value))
268 }
269}
270impl TryFrom<u16> for BismuthIsotope {
271 type Error = crate::errors::Error;
272 fn try_from(value: u16) -> Result<Self, Self::Error> {
273 Self::try_from(u64::from(value))
274 }
275}
276impl TryFrom<u32> for BismuthIsotope {
277 type Error = crate::errors::Error;
278 fn try_from(value: u32) -> Result<Self, Self::Error> {
279 Self::try_from(u64::from(value))
280 }
281}
282impl core::fmt::Display for BismuthIsotope {
283 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
284 match self {
285 Self::Bi184 => write!(f, "Bi184"),
286 Self::Bi185 => write!(f, "Bi185"),
287 Self::Bi186 => write!(f, "Bi186"),
288 Self::Bi187 => write!(f, "Bi187"),
289 Self::Bi188 => write!(f, "Bi188"),
290 Self::Bi189 => write!(f, "Bi189"),
291 Self::Bi190 => write!(f, "Bi190"),
292 Self::Bi191 => write!(f, "Bi191"),
293 Self::Bi192 => write!(f, "Bi192"),
294 Self::Bi193 => write!(f, "Bi193"),
295 Self::Bi194 => write!(f, "Bi194"),
296 Self::Bi195 => write!(f, "Bi195"),
297 Self::Bi196 => write!(f, "Bi196"),
298 Self::Bi197 => write!(f, "Bi197"),
299 Self::Bi198 => write!(f, "Bi198"),
300 Self::Bi199 => write!(f, "Bi199"),
301 Self::Bi200 => write!(f, "Bi200"),
302 Self::Bi201 => write!(f, "Bi201"),
303 Self::Bi202 => write!(f, "Bi202"),
304 Self::Bi203 => write!(f, "Bi203"),
305 Self::Bi204 => write!(f, "Bi204"),
306 Self::Bi205 => write!(f, "Bi205"),
307 Self::Bi206 => write!(f, "Bi206"),
308 Self::Bi207 => write!(f, "Bi207"),
309 Self::Bi208 => write!(f, "Bi208"),
310 Self::Bi209 => write!(f, "Bi209"),
311 Self::Bi210 => write!(f, "Bi210"),
312 Self::Bi211 => write!(f, "Bi211"),
313 Self::Bi212 => write!(f, "Bi212"),
314 Self::Bi213 => write!(f, "Bi213"),
315 Self::Bi214 => write!(f, "Bi214"),
316 Self::Bi215 => write!(f, "Bi215"),
317 Self::Bi216 => write!(f, "Bi216"),
318 Self::Bi217 => write!(f, "Bi217"),
319 Self::Bi218 => write!(f, "Bi218"),
320 Self::Bi219 => write!(f, "Bi219"),
321 Self::Bi220 => write!(f, "Bi220"),
322 Self::Bi221 => write!(f, "Bi221"),
323 Self::Bi222 => write!(f, "Bi222"),
324 Self::Bi223 => write!(f, "Bi223"),
325 Self::Bi224 => write!(f, "Bi224"),
326 }
327 }
328}
329#[cfg(test)]
330mod tests {
331 use strum::IntoEnumIterator;
332
333 use super::*;
334 use crate::isotopes::{
335 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
336 };
337 #[test]
338 fn test_relative_atomic_mass() {
339 for isotope in BismuthIsotope::iter() {
340 let mass = isotope.relative_atomic_mass();
341 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
342 }
343 }
344 #[test]
345 fn test_element() {
346 for isotope in BismuthIsotope::iter() {
347 let element = isotope.element();
348 assert_eq!(element, crate::Element::Bi, "Element should be correct for {isotope:?}");
349 }
350 }
351 #[test]
352 fn test_mass_number() {
353 for isotope in BismuthIsotope::iter() {
354 let mass_number = isotope.mass_number();
355 assert!(
356 mass_number > 0 && mass_number < 300,
357 "Mass number should be reasonable for {isotope:?}"
358 );
359 }
360 }
361 #[test]
362 fn test_isotopic_composition() {
363 for isotope in BismuthIsotope::iter() {
364 let comp = isotope.isotopic_composition();
365 if let Some(c) = comp {
366 assert!(
367 (0.0..=1.0).contains(&c),
368 "Composition should be between 0 and 1 for {isotope:?}"
369 );
370 }
371 }
372 }
373 #[test]
374 fn test_most_abundant() {
375 let most_abundant = BismuthIsotope::most_abundant_isotope();
376 let _ = most_abundant.relative_atomic_mass();
377 }
378 #[test]
379 fn test_from_isotope() {
380 for isotope in BismuthIsotope::iter() {
381 let iso: crate::Isotope = isotope.into();
382 match iso {
383 crate::Isotope::Bi(i) => assert_eq!(i, isotope),
384 _ => panic!("Wrong isotope type"),
385 }
386 }
387 }
388 #[test]
389 fn test_from_element() {
390 for isotope in BismuthIsotope::iter() {
391 let elem: crate::Element = isotope.into();
392 assert_eq!(elem, crate::Element::Bi);
393 }
394 }
395 #[test]
396 fn test_try_from_mass_number() {
397 for isotope in BismuthIsotope::iter() {
398 let mass = isotope.mass_number();
399 let iso = BismuthIsotope::try_from(mass).unwrap();
400 assert_eq!(iso, isotope);
401 let iso_u32 = BismuthIsotope::try_from(u32::from(mass)).unwrap();
402 assert_eq!(iso_u32, isotope);
403 if let Ok(mass_u8) = u8::try_from(mass) {
404 let iso_u8 = BismuthIsotope::try_from(mass_u8).unwrap();
405 assert_eq!(iso_u8, isotope);
406 }
407 }
408 assert!(BismuthIsotope::try_from(0_u16).is_err());
409 assert!(BismuthIsotope::try_from(1000_u16).is_err());
410 assert!(BismuthIsotope::try_from(0_u32).is_err());
411 assert!(BismuthIsotope::try_from(1000_u32).is_err());
412 assert!(BismuthIsotope::try_from(0_u8).is_err());
413 }
414 #[test]
415 fn test_display() {
416 for isotope in BismuthIsotope::iter() {
417 let s = alloc::format!("{isotope}");
418 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
419 }
420 }
421}