1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum CeriumIsotope {
6 Ce119,
8 Ce120,
10 Ce121,
12 Ce122,
14 Ce123,
16 Ce124,
18 Ce125,
20 Ce126,
22 Ce127,
24 Ce128,
26 Ce129,
28 Ce130,
30 Ce131,
32 Ce132,
34 Ce133,
36 Ce134,
38 Ce135,
40 Ce136,
42 Ce137,
44 Ce138,
46 Ce139,
48 Ce140,
50 Ce141,
52 Ce142,
54 Ce143,
56 Ce144,
58 Ce145,
60 Ce146,
62 Ce147,
64 Ce148,
66 Ce149,
68 Ce150,
70 Ce151,
72 Ce152,
74 Ce153,
76 Ce154,
78 Ce155,
80 Ce156,
82 Ce157,
84}
85impl super::RelativeAtomicMass for CeriumIsotope {
86 #[inline]
87 fn relative_atomic_mass(&self) -> f64 {
88 match self {
89 Self::Ce119 => 118.95271f64,
90 Self::Ce120 => 119.94654f64,
91 Self::Ce121 => 120.94335f64,
92 Self::Ce122 => 121.93787f64,
93 Self::Ce123 => 122.93528f64,
94 Self::Ce124 => 123.93031f64,
95 Self::Ce125 => 124.92844f64,
96 Self::Ce126 => 125.923971f64,
97 Self::Ce127 => 126.922727f64,
98 Self::Ce128 => 127.918911f64,
99 Self::Ce129 => 128.918102f64,
100 Self::Ce130 => 129.914736f64,
101 Self::Ce131 => 130.914429f64,
102 Self::Ce132 => 131.911464f64,
103 Self::Ce133 => 132.91152f64,
104 Self::Ce134 => 133.908928f64,
105 Self::Ce135 => 134.909161f64,
106 Self::Ce136 => 135.90712921f64,
107 Self::Ce137 => 136.90776236f64,
108 Self::Ce138 => 137.905991f64,
109 Self::Ce139 => 138.9066551f64,
110 Self::Ce140 => 139.9054431f64,
111 Self::Ce141 => 140.9082807f64,
112 Self::Ce142 => 141.9092504f64,
113 Self::Ce143 => 142.9123921f64,
114 Self::Ce144 => 143.9136529f64,
115 Self::Ce145 => 144.917265f64,
116 Self::Ce146 => 145.918802f64,
117 Self::Ce147 => 146.9226899f64,
118 Self::Ce148 => 147.924424f64,
119 Self::Ce149 => 148.928427f64,
120 Self::Ce150 => 149.930384f64,
121 Self::Ce151 => 150.934272f64,
122 Self::Ce152 => 151.9366f64,
123 Self::Ce153 => 152.94093f64,
124 Self::Ce154 => 153.9438f64,
125 Self::Ce155 => 154.94855f64,
126 Self::Ce156 => 155.95183f64,
127 Self::Ce157 => 156.95705f64,
128 }
129 }
130}
131impl super::ElementVariant for CeriumIsotope {
132 #[inline]
133 fn element(&self) -> crate::Element {
134 crate::Element::Ce
135 }
136}
137impl super::MassNumber for CeriumIsotope {
138 #[inline]
139 fn mass_number(&self) -> u16 {
140 match self {
141 Self::Ce119 => 119u16,
142 Self::Ce120 => 120u16,
143 Self::Ce121 => 121u16,
144 Self::Ce122 => 122u16,
145 Self::Ce123 => 123u16,
146 Self::Ce124 => 124u16,
147 Self::Ce125 => 125u16,
148 Self::Ce126 => 126u16,
149 Self::Ce127 => 127u16,
150 Self::Ce128 => 128u16,
151 Self::Ce129 => 129u16,
152 Self::Ce130 => 130u16,
153 Self::Ce131 => 131u16,
154 Self::Ce132 => 132u16,
155 Self::Ce133 => 133u16,
156 Self::Ce134 => 134u16,
157 Self::Ce135 => 135u16,
158 Self::Ce136 => 136u16,
159 Self::Ce137 => 137u16,
160 Self::Ce138 => 138u16,
161 Self::Ce139 => 139u16,
162 Self::Ce140 => 140u16,
163 Self::Ce141 => 141u16,
164 Self::Ce142 => 142u16,
165 Self::Ce143 => 143u16,
166 Self::Ce144 => 144u16,
167 Self::Ce145 => 145u16,
168 Self::Ce146 => 146u16,
169 Self::Ce147 => 147u16,
170 Self::Ce148 => 148u16,
171 Self::Ce149 => 149u16,
172 Self::Ce150 => 150u16,
173 Self::Ce151 => 151u16,
174 Self::Ce152 => 152u16,
175 Self::Ce153 => 153u16,
176 Self::Ce154 => 154u16,
177 Self::Ce155 => 155u16,
178 Self::Ce156 => 156u16,
179 Self::Ce157 => 157u16,
180 }
181 }
182}
183impl super::IsotopicComposition for CeriumIsotope {
184 #[inline]
185 fn isotopic_composition(&self) -> Option<f64> {
186 match self {
187 Self::Ce136 => Some(0.00185f64),
188 Self::Ce138 => Some(0.00251f64),
189 Self::Ce140 => Some(0.8845f64),
190 Self::Ce142 => Some(0.11114f64),
191 _ => None,
192 }
193 }
194}
195impl super::MostAbundantIsotope for CeriumIsotope {
196 fn most_abundant_isotope() -> Self {
197 Self::Ce140
198 }
199}
200impl From<CeriumIsotope> for crate::Isotope {
201 fn from(isotope: CeriumIsotope) -> Self {
202 crate::Isotope::Ce(isotope)
203 }
204}
205impl From<CeriumIsotope> for crate::Element {
206 fn from(_isotope: CeriumIsotope) -> Self {
207 crate::Element::Ce
208 }
209}
210impl TryFrom<u64> for CeriumIsotope {
211 type Error = crate::errors::Error;
212 fn try_from(value: u64) -> Result<Self, Self::Error> {
213 match value {
214 119u64 => Ok(Self::Ce119),
215 120u64 => Ok(Self::Ce120),
216 121u64 => Ok(Self::Ce121),
217 122u64 => Ok(Self::Ce122),
218 123u64 => Ok(Self::Ce123),
219 124u64 => Ok(Self::Ce124),
220 125u64 => Ok(Self::Ce125),
221 126u64 => Ok(Self::Ce126),
222 127u64 => Ok(Self::Ce127),
223 128u64 => Ok(Self::Ce128),
224 129u64 => Ok(Self::Ce129),
225 130u64 => Ok(Self::Ce130),
226 131u64 => Ok(Self::Ce131),
227 132u64 => Ok(Self::Ce132),
228 133u64 => Ok(Self::Ce133),
229 134u64 => Ok(Self::Ce134),
230 135u64 => Ok(Self::Ce135),
231 136u64 => Ok(Self::Ce136),
232 137u64 => Ok(Self::Ce137),
233 138u64 => Ok(Self::Ce138),
234 139u64 => Ok(Self::Ce139),
235 140u64 => Ok(Self::Ce140),
236 141u64 => Ok(Self::Ce141),
237 142u64 => Ok(Self::Ce142),
238 143u64 => Ok(Self::Ce143),
239 144u64 => Ok(Self::Ce144),
240 145u64 => Ok(Self::Ce145),
241 146u64 => Ok(Self::Ce146),
242 147u64 => Ok(Self::Ce147),
243 148u64 => Ok(Self::Ce148),
244 149u64 => Ok(Self::Ce149),
245 150u64 => Ok(Self::Ce150),
246 151u64 => Ok(Self::Ce151),
247 152u64 => Ok(Self::Ce152),
248 153u64 => Ok(Self::Ce153),
249 154u64 => Ok(Self::Ce154),
250 155u64 => Ok(Self::Ce155),
251 156u64 => Ok(Self::Ce156),
252 157u64 => Ok(Self::Ce157),
253 _ => Err(crate::errors::Error::Isotope(crate::Element::Ce, value)),
254 }
255 }
256}
257impl TryFrom<u8> for CeriumIsotope {
258 type Error = crate::errors::Error;
259 fn try_from(value: u8) -> Result<Self, Self::Error> {
260 Self::try_from(u64::from(value))
261 }
262}
263impl TryFrom<u16> for CeriumIsotope {
264 type Error = crate::errors::Error;
265 fn try_from(value: u16) -> Result<Self, Self::Error> {
266 Self::try_from(u64::from(value))
267 }
268}
269impl TryFrom<u32> for CeriumIsotope {
270 type Error = crate::errors::Error;
271 fn try_from(value: u32) -> Result<Self, Self::Error> {
272 Self::try_from(u64::from(value))
273 }
274}
275impl core::fmt::Display for CeriumIsotope {
276 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
277 match self {
278 Self::Ce119 => write!(f, "Ce119"),
279 Self::Ce120 => write!(f, "Ce120"),
280 Self::Ce121 => write!(f, "Ce121"),
281 Self::Ce122 => write!(f, "Ce122"),
282 Self::Ce123 => write!(f, "Ce123"),
283 Self::Ce124 => write!(f, "Ce124"),
284 Self::Ce125 => write!(f, "Ce125"),
285 Self::Ce126 => write!(f, "Ce126"),
286 Self::Ce127 => write!(f, "Ce127"),
287 Self::Ce128 => write!(f, "Ce128"),
288 Self::Ce129 => write!(f, "Ce129"),
289 Self::Ce130 => write!(f, "Ce130"),
290 Self::Ce131 => write!(f, "Ce131"),
291 Self::Ce132 => write!(f, "Ce132"),
292 Self::Ce133 => write!(f, "Ce133"),
293 Self::Ce134 => write!(f, "Ce134"),
294 Self::Ce135 => write!(f, "Ce135"),
295 Self::Ce136 => write!(f, "Ce136"),
296 Self::Ce137 => write!(f, "Ce137"),
297 Self::Ce138 => write!(f, "Ce138"),
298 Self::Ce139 => write!(f, "Ce139"),
299 Self::Ce140 => write!(f, "Ce140"),
300 Self::Ce141 => write!(f, "Ce141"),
301 Self::Ce142 => write!(f, "Ce142"),
302 Self::Ce143 => write!(f, "Ce143"),
303 Self::Ce144 => write!(f, "Ce144"),
304 Self::Ce145 => write!(f, "Ce145"),
305 Self::Ce146 => write!(f, "Ce146"),
306 Self::Ce147 => write!(f, "Ce147"),
307 Self::Ce148 => write!(f, "Ce148"),
308 Self::Ce149 => write!(f, "Ce149"),
309 Self::Ce150 => write!(f, "Ce150"),
310 Self::Ce151 => write!(f, "Ce151"),
311 Self::Ce152 => write!(f, "Ce152"),
312 Self::Ce153 => write!(f, "Ce153"),
313 Self::Ce154 => write!(f, "Ce154"),
314 Self::Ce155 => write!(f, "Ce155"),
315 Self::Ce156 => write!(f, "Ce156"),
316 Self::Ce157 => write!(f, "Ce157"),
317 }
318 }
319}
320#[cfg(test)]
321mod tests {
322 use strum::IntoEnumIterator;
323
324 use super::*;
325 use crate::isotopes::{
326 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
327 };
328 #[test]
329 fn test_relative_atomic_mass() {
330 for isotope in CeriumIsotope::iter() {
331 let mass = isotope.relative_atomic_mass();
332 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
333 }
334 }
335 #[test]
336 fn test_element() {
337 for isotope in CeriumIsotope::iter() {
338 let element = isotope.element();
339 assert_eq!(element, crate::Element::Ce, "Element should be correct for {isotope:?}");
340 }
341 }
342 #[test]
343 fn test_mass_number() {
344 for isotope in CeriumIsotope::iter() {
345 let mass_number = isotope.mass_number();
346 assert!(
347 mass_number > 0 && mass_number < 300,
348 "Mass number should be reasonable for {isotope:?}"
349 );
350 }
351 }
352 #[test]
353 fn test_isotopic_composition() {
354 for isotope in CeriumIsotope::iter() {
355 let comp = isotope.isotopic_composition();
356 if let Some(c) = comp {
357 assert!(
358 (0.0..=1.0).contains(&c),
359 "Composition should be between 0 and 1 for {isotope:?}"
360 );
361 }
362 }
363 }
364 #[test]
365 fn test_most_abundant() {
366 let most_abundant = CeriumIsotope::most_abundant_isotope();
367 let _ = most_abundant.relative_atomic_mass();
368 }
369 #[test]
370 fn test_from_isotope() {
371 for isotope in CeriumIsotope::iter() {
372 let iso: crate::Isotope = isotope.into();
373 match iso {
374 crate::Isotope::Ce(i) => assert_eq!(i, isotope),
375 _ => panic!("Wrong isotope type"),
376 }
377 }
378 }
379 #[test]
380 fn test_from_element() {
381 for isotope in CeriumIsotope::iter() {
382 let elem: crate::Element = isotope.into();
383 assert_eq!(elem, crate::Element::Ce);
384 }
385 }
386 #[test]
387 fn test_try_from_mass_number() {
388 for isotope in CeriumIsotope::iter() {
389 let mass = isotope.mass_number();
390 let iso = CeriumIsotope::try_from(mass).unwrap();
391 assert_eq!(iso, isotope);
392 let iso_u32 = CeriumIsotope::try_from(u32::from(mass)).unwrap();
393 assert_eq!(iso_u32, isotope);
394 if let Ok(mass_u8) = u8::try_from(mass) {
395 let iso_u8 = CeriumIsotope::try_from(mass_u8).unwrap();
396 assert_eq!(iso_u8, isotope);
397 }
398 }
399 assert!(CeriumIsotope::try_from(0_u16).is_err());
400 assert!(CeriumIsotope::try_from(1000_u16).is_err());
401 assert!(CeriumIsotope::try_from(0_u32).is_err());
402 assert!(CeriumIsotope::try_from(1000_u32).is_err());
403 assert!(CeriumIsotope::try_from(0_u8).is_err());
404 }
405 #[test]
406 fn test_display() {
407 for isotope in CeriumIsotope::iter() {
408 let s = alloc::format!("{isotope}");
409 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
410 }
411 }
412}