1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum XenonIsotope {
6 Xe109,
8 Xe110,
10 Xe111,
12 Xe112,
14 Xe113,
16 Xe114,
18 Xe115,
20 Xe116,
22 Xe117,
24 Xe118,
26 Xe119,
28 Xe120,
30 Xe121,
32 Xe122,
34 Xe123,
36 Xe124,
38 Xe125,
40 Xe126,
42 Xe127,
44 Xe128,
46 Xe129,
48 Xe130,
50 Xe131,
52 Xe132,
54 Xe133,
56 Xe134,
58 Xe135,
60 Xe136,
62 Xe137,
64 Xe138,
66 Xe139,
68 Xe140,
70 Xe141,
72 Xe142,
74 Xe143,
76 Xe144,
78 Xe145,
80 Xe146,
82 Xe147,
84 Xe148,
86}
87impl super::RelativeAtomicMass for XenonIsotope {
88 #[inline]
89 fn relative_atomic_mass(&self) -> f64 {
90 match self {
91 Self::Xe109 => 108.95043f64,
92 Self::Xe110 => 109.94426f64,
93 Self::Xe111 => 110.941607f64,
94 Self::Xe112 => 111.935559f64,
95 Self::Xe113 => 112.9332217f64,
96 Self::Xe114 => 113.92798f64,
97 Self::Xe115 => 114.926294f64,
98 Self::Xe116 => 115.921581f64,
99 Self::Xe117 => 116.920359f64,
100 Self::Xe118 => 117.916179f64,
101 Self::Xe119 => 118.915411f64,
102 Self::Xe120 => 119.911784f64,
103 Self::Xe121 => 120.911453f64,
104 Self::Xe122 => 121.908368f64,
105 Self::Xe123 => 122.908482f64,
106 Self::Xe124 => 123.905892f64,
107 Self::Xe125 => 124.9063944f64,
108 Self::Xe126 => 125.9042983f64,
109 Self::Xe127 => 126.9051829f64,
110 Self::Xe128 => 127.903531f64,
111 Self::Xe129 => 128.9047808611f64,
112 Self::Xe130 => 129.903509349f64,
113 Self::Xe131 => 130.90508406f64,
114 Self::Xe132 => 131.9041550856f64,
115 Self::Xe133 => 132.9059108f64,
116 Self::Xe134 => 133.90539466f64,
117 Self::Xe135 => 134.9072278f64,
118 Self::Xe136 => 135.907214484f64,
119 Self::Xe137 => 136.91155778f64,
120 Self::Xe138 => 137.9141463f64,
121 Self::Xe139 => 138.9187922f64,
122 Self::Xe140 => 139.9216458f64,
123 Self::Xe141 => 140.9267872f64,
124 Self::Xe142 => 141.9299731f64,
125 Self::Xe143 => 142.9353696f64,
126 Self::Xe144 => 143.9389451f64,
127 Self::Xe145 => 144.94472f64,
128 Self::Xe146 => 145.948518f64,
129 Self::Xe147 => 146.95426f64,
130 Self::Xe148 => 147.95813f64,
131 }
132 }
133}
134impl super::ElementVariant for XenonIsotope {
135 #[inline]
136 fn element(&self) -> crate::Element {
137 crate::Element::Xe
138 }
139}
140impl super::MassNumber for XenonIsotope {
141 #[inline]
142 fn mass_number(&self) -> u16 {
143 match self {
144 Self::Xe109 => 109u16,
145 Self::Xe110 => 110u16,
146 Self::Xe111 => 111u16,
147 Self::Xe112 => 112u16,
148 Self::Xe113 => 113u16,
149 Self::Xe114 => 114u16,
150 Self::Xe115 => 115u16,
151 Self::Xe116 => 116u16,
152 Self::Xe117 => 117u16,
153 Self::Xe118 => 118u16,
154 Self::Xe119 => 119u16,
155 Self::Xe120 => 120u16,
156 Self::Xe121 => 121u16,
157 Self::Xe122 => 122u16,
158 Self::Xe123 => 123u16,
159 Self::Xe124 => 124u16,
160 Self::Xe125 => 125u16,
161 Self::Xe126 => 126u16,
162 Self::Xe127 => 127u16,
163 Self::Xe128 => 128u16,
164 Self::Xe129 => 129u16,
165 Self::Xe130 => 130u16,
166 Self::Xe131 => 131u16,
167 Self::Xe132 => 132u16,
168 Self::Xe133 => 133u16,
169 Self::Xe134 => 134u16,
170 Self::Xe135 => 135u16,
171 Self::Xe136 => 136u16,
172 Self::Xe137 => 137u16,
173 Self::Xe138 => 138u16,
174 Self::Xe139 => 139u16,
175 Self::Xe140 => 140u16,
176 Self::Xe141 => 141u16,
177 Self::Xe142 => 142u16,
178 Self::Xe143 => 143u16,
179 Self::Xe144 => 144u16,
180 Self::Xe145 => 145u16,
181 Self::Xe146 => 146u16,
182 Self::Xe147 => 147u16,
183 Self::Xe148 => 148u16,
184 }
185 }
186}
187impl super::IsotopicComposition for XenonIsotope {
188 #[inline]
189 fn isotopic_composition(&self) -> Option<f64> {
190 match self {
191 Self::Xe124 => Some(0.000952f64),
192 Self::Xe126 => Some(0.00089f64),
193 Self::Xe128 => Some(0.019102f64),
194 Self::Xe129 => Some(0.264006f64),
195 Self::Xe130 => Some(0.04071f64),
196 Self::Xe131 => Some(0.212324f64),
197 Self::Xe132 => Some(0.269086f64),
198 Self::Xe134 => Some(0.104357f64),
199 Self::Xe136 => Some(0.088573f64),
200 _ => None,
201 }
202 }
203}
204impl super::MostAbundantIsotope for XenonIsotope {
205 fn most_abundant_isotope() -> Self {
206 Self::Xe132
207 }
208}
209impl From<XenonIsotope> for crate::Isotope {
210 fn from(isotope: XenonIsotope) -> Self {
211 crate::Isotope::Xe(isotope)
212 }
213}
214impl From<XenonIsotope> for crate::Element {
215 fn from(_isotope: XenonIsotope) -> Self {
216 crate::Element::Xe
217 }
218}
219impl TryFrom<u64> for XenonIsotope {
220 type Error = crate::errors::Error;
221 fn try_from(value: u64) -> Result<Self, Self::Error> {
222 match value {
223 109u64 => Ok(Self::Xe109),
224 110u64 => Ok(Self::Xe110),
225 111u64 => Ok(Self::Xe111),
226 112u64 => Ok(Self::Xe112),
227 113u64 => Ok(Self::Xe113),
228 114u64 => Ok(Self::Xe114),
229 115u64 => Ok(Self::Xe115),
230 116u64 => Ok(Self::Xe116),
231 117u64 => Ok(Self::Xe117),
232 118u64 => Ok(Self::Xe118),
233 119u64 => Ok(Self::Xe119),
234 120u64 => Ok(Self::Xe120),
235 121u64 => Ok(Self::Xe121),
236 122u64 => Ok(Self::Xe122),
237 123u64 => Ok(Self::Xe123),
238 124u64 => Ok(Self::Xe124),
239 125u64 => Ok(Self::Xe125),
240 126u64 => Ok(Self::Xe126),
241 127u64 => Ok(Self::Xe127),
242 128u64 => Ok(Self::Xe128),
243 129u64 => Ok(Self::Xe129),
244 130u64 => Ok(Self::Xe130),
245 131u64 => Ok(Self::Xe131),
246 132u64 => Ok(Self::Xe132),
247 133u64 => Ok(Self::Xe133),
248 134u64 => Ok(Self::Xe134),
249 135u64 => Ok(Self::Xe135),
250 136u64 => Ok(Self::Xe136),
251 137u64 => Ok(Self::Xe137),
252 138u64 => Ok(Self::Xe138),
253 139u64 => Ok(Self::Xe139),
254 140u64 => Ok(Self::Xe140),
255 141u64 => Ok(Self::Xe141),
256 142u64 => Ok(Self::Xe142),
257 143u64 => Ok(Self::Xe143),
258 144u64 => Ok(Self::Xe144),
259 145u64 => Ok(Self::Xe145),
260 146u64 => Ok(Self::Xe146),
261 147u64 => Ok(Self::Xe147),
262 148u64 => Ok(Self::Xe148),
263 _ => Err(crate::errors::Error::Isotope(crate::Element::Xe, value)),
264 }
265 }
266}
267impl TryFrom<u8> for XenonIsotope {
268 type Error = crate::errors::Error;
269 fn try_from(value: u8) -> Result<Self, Self::Error> {
270 Self::try_from(u64::from(value))
271 }
272}
273impl TryFrom<u16> for XenonIsotope {
274 type Error = crate::errors::Error;
275 fn try_from(value: u16) -> Result<Self, Self::Error> {
276 Self::try_from(u64::from(value))
277 }
278}
279impl TryFrom<u32> for XenonIsotope {
280 type Error = crate::errors::Error;
281 fn try_from(value: u32) -> Result<Self, Self::Error> {
282 Self::try_from(u64::from(value))
283 }
284}
285impl core::fmt::Display for XenonIsotope {
286 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
287 match self {
288 Self::Xe109 => write!(f, "Xe109"),
289 Self::Xe110 => write!(f, "Xe110"),
290 Self::Xe111 => write!(f, "Xe111"),
291 Self::Xe112 => write!(f, "Xe112"),
292 Self::Xe113 => write!(f, "Xe113"),
293 Self::Xe114 => write!(f, "Xe114"),
294 Self::Xe115 => write!(f, "Xe115"),
295 Self::Xe116 => write!(f, "Xe116"),
296 Self::Xe117 => write!(f, "Xe117"),
297 Self::Xe118 => write!(f, "Xe118"),
298 Self::Xe119 => write!(f, "Xe119"),
299 Self::Xe120 => write!(f, "Xe120"),
300 Self::Xe121 => write!(f, "Xe121"),
301 Self::Xe122 => write!(f, "Xe122"),
302 Self::Xe123 => write!(f, "Xe123"),
303 Self::Xe124 => write!(f, "Xe124"),
304 Self::Xe125 => write!(f, "Xe125"),
305 Self::Xe126 => write!(f, "Xe126"),
306 Self::Xe127 => write!(f, "Xe127"),
307 Self::Xe128 => write!(f, "Xe128"),
308 Self::Xe129 => write!(f, "Xe129"),
309 Self::Xe130 => write!(f, "Xe130"),
310 Self::Xe131 => write!(f, "Xe131"),
311 Self::Xe132 => write!(f, "Xe132"),
312 Self::Xe133 => write!(f, "Xe133"),
313 Self::Xe134 => write!(f, "Xe134"),
314 Self::Xe135 => write!(f, "Xe135"),
315 Self::Xe136 => write!(f, "Xe136"),
316 Self::Xe137 => write!(f, "Xe137"),
317 Self::Xe138 => write!(f, "Xe138"),
318 Self::Xe139 => write!(f, "Xe139"),
319 Self::Xe140 => write!(f, "Xe140"),
320 Self::Xe141 => write!(f, "Xe141"),
321 Self::Xe142 => write!(f, "Xe142"),
322 Self::Xe143 => write!(f, "Xe143"),
323 Self::Xe144 => write!(f, "Xe144"),
324 Self::Xe145 => write!(f, "Xe145"),
325 Self::Xe146 => write!(f, "Xe146"),
326 Self::Xe147 => write!(f, "Xe147"),
327 Self::Xe148 => write!(f, "Xe148"),
328 }
329 }
330}
331#[cfg(test)]
332mod tests {
333 use strum::IntoEnumIterator;
334
335 use super::*;
336 use crate::isotopes::{
337 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
338 };
339 #[test]
340 fn test_relative_atomic_mass() {
341 for isotope in XenonIsotope::iter() {
342 let mass = isotope.relative_atomic_mass();
343 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
344 }
345 }
346 #[test]
347 fn test_element() {
348 for isotope in XenonIsotope::iter() {
349 let element = isotope.element();
350 assert_eq!(element, crate::Element::Xe, "Element should be correct for {isotope:?}");
351 }
352 }
353 #[test]
354 fn test_mass_number() {
355 for isotope in XenonIsotope::iter() {
356 let mass_number = isotope.mass_number();
357 assert!(
358 mass_number > 0 && mass_number < 300,
359 "Mass number should be reasonable for {isotope:?}"
360 );
361 }
362 }
363 #[test]
364 fn test_isotopic_composition() {
365 for isotope in XenonIsotope::iter() {
366 let comp = isotope.isotopic_composition();
367 if let Some(c) = comp {
368 assert!(
369 (0.0..=1.0).contains(&c),
370 "Composition should be between 0 and 1 for {isotope:?}"
371 );
372 }
373 }
374 }
375 #[test]
376 fn test_most_abundant() {
377 let most_abundant = XenonIsotope::most_abundant_isotope();
378 let _ = most_abundant.relative_atomic_mass();
379 }
380 #[test]
381 fn test_from_isotope() {
382 for isotope in XenonIsotope::iter() {
383 let iso: crate::Isotope = isotope.into();
384 match iso {
385 crate::Isotope::Xe(i) => assert_eq!(i, isotope),
386 _ => panic!("Wrong isotope type"),
387 }
388 }
389 }
390 #[test]
391 fn test_from_element() {
392 for isotope in XenonIsotope::iter() {
393 let elem: crate::Element = isotope.into();
394 assert_eq!(elem, crate::Element::Xe);
395 }
396 }
397 #[test]
398 fn test_try_from_mass_number() {
399 for isotope in XenonIsotope::iter() {
400 let mass = isotope.mass_number();
401 let iso = XenonIsotope::try_from(mass).unwrap();
402 assert_eq!(iso, isotope);
403 let iso_u32 = XenonIsotope::try_from(u32::from(mass)).unwrap();
404 assert_eq!(iso_u32, isotope);
405 if let Ok(mass_u8) = u8::try_from(mass) {
406 let iso_u8 = XenonIsotope::try_from(mass_u8).unwrap();
407 assert_eq!(iso_u8, isotope);
408 }
409 }
410 assert!(XenonIsotope::try_from(0_u16).is_err());
411 assert!(XenonIsotope::try_from(1000_u16).is_err());
412 assert!(XenonIsotope::try_from(0_u32).is_err());
413 assert!(XenonIsotope::try_from(1000_u32).is_err());
414 assert!(XenonIsotope::try_from(0_u8).is_err());
415 }
416 #[test]
417 fn test_display() {
418 for isotope in XenonIsotope::iter() {
419 let s = alloc::format!("{isotope}");
420 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
421 }
422 }
423}