1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
5pub enum DysprosiumIsotope {
7 Dy138,
9 Dy139,
11 Dy140,
13 Dy141,
15 Dy142,
17 Dy143,
19 Dy144,
21 Dy145,
23 Dy146,
25 Dy147,
27 Dy148,
29 Dy149,
31 Dy150,
33 Dy151,
35 Dy152,
37 Dy153,
39 Dy154,
41 Dy155,
43 Dy156,
45 Dy157,
47 Dy158,
49 Dy159,
51 Dy160,
53 Dy161,
55 Dy162,
57 Dy163,
59 Dy164,
61 Dy165,
63 Dy166,
65 Dy167,
67 Dy168,
69 Dy169,
71 Dy170,
73 Dy171,
75 Dy172,
77 Dy173,
79}
80impl super::RelativeAtomicMass for DysprosiumIsotope {
81 #[inline]
82 fn relative_atomic_mass(&self) -> f64 {
83 match self {
84 Self::Dy138 => 137.9625f64,
85 Self::Dy139 => 138.95959f64,
86 Self::Dy140 => 139.95402f64,
87 Self::Dy141 => 140.95128f64,
88 Self::Dy142 => 141.94619f64,
89 Self::Dy143 => 142.943994f64,
90 Self::Dy144 => 143.9392695f64,
91 Self::Dy145 => 144.937474f64,
92 Self::Dy146 => 145.9328445f64,
93 Self::Dy147 => 146.9310827f64,
94 Self::Dy148 => 147.927157f64,
95 Self::Dy149 => 148.927322f64,
96 Self::Dy150 => 149.9255933f64,
97 Self::Dy151 => 150.9261916f64,
98 Self::Dy152 => 151.9247253f64,
99 Self::Dy153 => 152.9257724f64,
100 Self::Dy154 => 153.9244293f64,
101 Self::Dy155 => 154.925759f64,
102 Self::Dy156 => 155.9242847f64,
103 Self::Dy157 => 156.9254707f64,
104 Self::Dy158 => 157.9244159f64,
105 Self::Dy159 => 158.925747f64,
106 Self::Dy160 => 159.9252046f64,
107 Self::Dy161 => 160.9269405f64,
108 Self::Dy162 => 161.9268056f64,
109 Self::Dy163 => 162.9287383f64,
110 Self::Dy164 => 163.9291819f64,
111 Self::Dy165 => 164.9317105f64,
112 Self::Dy166 => 165.9328139f64,
113 Self::Dy167 => 166.935661f64,
114 Self::Dy168 => 167.93713f64,
115 Self::Dy169 => 168.94031f64,
116 Self::Dy170 => 169.94239f64,
117 Self::Dy171 => 170.94612f64,
118 Self::Dy172 => 171.94846f64,
119 Self::Dy173 => 172.95283f64,
120 }
121 }
122}
123impl super::ElementVariant for DysprosiumIsotope {
124 #[inline]
125 fn element(&self) -> crate::Element {
126 crate::Element::Dy
127 }
128}
129impl super::MassNumber for DysprosiumIsotope {
130 #[inline]
131 fn mass_number(&self) -> u16 {
132 match self {
133 Self::Dy138 => 138u16,
134 Self::Dy139 => 139u16,
135 Self::Dy140 => 140u16,
136 Self::Dy141 => 141u16,
137 Self::Dy142 => 142u16,
138 Self::Dy143 => 143u16,
139 Self::Dy144 => 144u16,
140 Self::Dy145 => 145u16,
141 Self::Dy146 => 146u16,
142 Self::Dy147 => 147u16,
143 Self::Dy148 => 148u16,
144 Self::Dy149 => 149u16,
145 Self::Dy150 => 150u16,
146 Self::Dy151 => 151u16,
147 Self::Dy152 => 152u16,
148 Self::Dy153 => 153u16,
149 Self::Dy154 => 154u16,
150 Self::Dy155 => 155u16,
151 Self::Dy156 => 156u16,
152 Self::Dy157 => 157u16,
153 Self::Dy158 => 158u16,
154 Self::Dy159 => 159u16,
155 Self::Dy160 => 160u16,
156 Self::Dy161 => 161u16,
157 Self::Dy162 => 162u16,
158 Self::Dy163 => 163u16,
159 Self::Dy164 => 164u16,
160 Self::Dy165 => 165u16,
161 Self::Dy166 => 166u16,
162 Self::Dy167 => 167u16,
163 Self::Dy168 => 168u16,
164 Self::Dy169 => 169u16,
165 Self::Dy170 => 170u16,
166 Self::Dy171 => 171u16,
167 Self::Dy172 => 172u16,
168 Self::Dy173 => 173u16,
169 }
170 }
171}
172impl super::IsotopicComposition for DysprosiumIsotope {
173 #[inline]
174 fn isotopic_composition(&self) -> Option<f64> {
175 match self {
176 Self::Dy156 => Some(0.00056f64),
177 Self::Dy158 => Some(0.00095f64),
178 Self::Dy160 => Some(0.02329f64),
179 Self::Dy161 => Some(0.18889f64),
180 Self::Dy162 => Some(0.25475f64),
181 Self::Dy163 => Some(0.24896f64),
182 Self::Dy164 => Some(0.2826f64),
183 _ => None,
184 }
185 }
186}
187impl super::MostAbundantIsotope for DysprosiumIsotope {
188 fn most_abundant_isotope() -> Self {
189 Self::Dy164
190 }
191}
192impl From<DysprosiumIsotope> for crate::Isotope {
193 fn from(isotope: DysprosiumIsotope) -> Self {
194 crate::Isotope::Dy(isotope)
195 }
196}
197impl From<DysprosiumIsotope> for crate::Element {
198 fn from(_isotope: DysprosiumIsotope) -> Self {
199 crate::Element::Dy
200 }
201}
202impl TryFrom<u64> for DysprosiumIsotope {
203 type Error = crate::errors::Error;
204 fn try_from(value: u64) -> Result<Self, Self::Error> {
205 match value {
206 138u64 => Ok(Self::Dy138),
207 139u64 => Ok(Self::Dy139),
208 140u64 => Ok(Self::Dy140),
209 141u64 => Ok(Self::Dy141),
210 142u64 => Ok(Self::Dy142),
211 143u64 => Ok(Self::Dy143),
212 144u64 => Ok(Self::Dy144),
213 145u64 => Ok(Self::Dy145),
214 146u64 => Ok(Self::Dy146),
215 147u64 => Ok(Self::Dy147),
216 148u64 => Ok(Self::Dy148),
217 149u64 => Ok(Self::Dy149),
218 150u64 => Ok(Self::Dy150),
219 151u64 => Ok(Self::Dy151),
220 152u64 => Ok(Self::Dy152),
221 153u64 => Ok(Self::Dy153),
222 154u64 => Ok(Self::Dy154),
223 155u64 => Ok(Self::Dy155),
224 156u64 => Ok(Self::Dy156),
225 157u64 => Ok(Self::Dy157),
226 158u64 => Ok(Self::Dy158),
227 159u64 => Ok(Self::Dy159),
228 160u64 => Ok(Self::Dy160),
229 161u64 => Ok(Self::Dy161),
230 162u64 => Ok(Self::Dy162),
231 163u64 => Ok(Self::Dy163),
232 164u64 => Ok(Self::Dy164),
233 165u64 => Ok(Self::Dy165),
234 166u64 => Ok(Self::Dy166),
235 167u64 => Ok(Self::Dy167),
236 168u64 => Ok(Self::Dy168),
237 169u64 => Ok(Self::Dy169),
238 170u64 => Ok(Self::Dy170),
239 171u64 => Ok(Self::Dy171),
240 172u64 => Ok(Self::Dy172),
241 173u64 => Ok(Self::Dy173),
242 _ => Err(crate::errors::Error::Isotope(crate::Element::Dy, value)),
243 }
244 }
245}
246impl TryFrom<u8> for DysprosiumIsotope {
247 type Error = crate::errors::Error;
248 fn try_from(value: u8) -> Result<Self, Self::Error> {
249 Self::try_from(u64::from(value))
250 }
251}
252impl TryFrom<u16> for DysprosiumIsotope {
253 type Error = crate::errors::Error;
254 fn try_from(value: u16) -> Result<Self, Self::Error> {
255 Self::try_from(u64::from(value))
256 }
257}
258impl TryFrom<u32> for DysprosiumIsotope {
259 type Error = crate::errors::Error;
260 fn try_from(value: u32) -> Result<Self, Self::Error> {
261 Self::try_from(u64::from(value))
262 }
263}
264impl core::fmt::Display for DysprosiumIsotope {
265 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266 match self {
267 Self::Dy138 => write!(f, "Dy138"),
268 Self::Dy139 => write!(f, "Dy139"),
269 Self::Dy140 => write!(f, "Dy140"),
270 Self::Dy141 => write!(f, "Dy141"),
271 Self::Dy142 => write!(f, "Dy142"),
272 Self::Dy143 => write!(f, "Dy143"),
273 Self::Dy144 => write!(f, "Dy144"),
274 Self::Dy145 => write!(f, "Dy145"),
275 Self::Dy146 => write!(f, "Dy146"),
276 Self::Dy147 => write!(f, "Dy147"),
277 Self::Dy148 => write!(f, "Dy148"),
278 Self::Dy149 => write!(f, "Dy149"),
279 Self::Dy150 => write!(f, "Dy150"),
280 Self::Dy151 => write!(f, "Dy151"),
281 Self::Dy152 => write!(f, "Dy152"),
282 Self::Dy153 => write!(f, "Dy153"),
283 Self::Dy154 => write!(f, "Dy154"),
284 Self::Dy155 => write!(f, "Dy155"),
285 Self::Dy156 => write!(f, "Dy156"),
286 Self::Dy157 => write!(f, "Dy157"),
287 Self::Dy158 => write!(f, "Dy158"),
288 Self::Dy159 => write!(f, "Dy159"),
289 Self::Dy160 => write!(f, "Dy160"),
290 Self::Dy161 => write!(f, "Dy161"),
291 Self::Dy162 => write!(f, "Dy162"),
292 Self::Dy163 => write!(f, "Dy163"),
293 Self::Dy164 => write!(f, "Dy164"),
294 Self::Dy165 => write!(f, "Dy165"),
295 Self::Dy166 => write!(f, "Dy166"),
296 Self::Dy167 => write!(f, "Dy167"),
297 Self::Dy168 => write!(f, "Dy168"),
298 Self::Dy169 => write!(f, "Dy169"),
299 Self::Dy170 => write!(f, "Dy170"),
300 Self::Dy171 => write!(f, "Dy171"),
301 Self::Dy172 => write!(f, "Dy172"),
302 Self::Dy173 => write!(f, "Dy173"),
303 }
304 }
305}
306#[cfg(test)]
307mod tests {
308 use strum::IntoEnumIterator;
309
310 use super::*;
311 use crate::isotopes::{
312 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
313 };
314 #[test]
315 fn test_relative_atomic_mass() {
316 for isotope in DysprosiumIsotope::iter() {
317 let mass = isotope.relative_atomic_mass();
318 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
319 }
320 }
321 #[test]
322 fn test_element() {
323 for isotope in DysprosiumIsotope::iter() {
324 let element = isotope.element();
325 assert_eq!(element, crate::Element::Dy, "Element should be correct for {isotope:?}");
326 }
327 }
328 #[test]
329 fn test_mass_number() {
330 for isotope in DysprosiumIsotope::iter() {
331 let mass_number = isotope.mass_number();
332 assert!(
333 mass_number > 0 && mass_number < 300,
334 "Mass number should be reasonable for {isotope:?}"
335 );
336 }
337 }
338 #[test]
339 fn test_isotopic_composition() {
340 for isotope in DysprosiumIsotope::iter() {
341 let comp = isotope.isotopic_composition();
342 if let Some(c) = comp {
343 assert!(
344 (0.0..=1.0).contains(&c),
345 "Composition should be between 0 and 1 for {isotope:?}"
346 );
347 }
348 }
349 }
350 #[test]
351 fn test_most_abundant() {
352 let most_abundant = DysprosiumIsotope::most_abundant_isotope();
353 let _ = most_abundant.relative_atomic_mass();
354 }
355 #[test]
356 fn test_from_isotope() {
357 for isotope in DysprosiumIsotope::iter() {
358 let iso: crate::Isotope = isotope.into();
359 match iso {
360 crate::Isotope::Dy(i) => assert_eq!(i, isotope),
361 _ => panic!("Wrong isotope type"),
362 }
363 }
364 }
365 #[test]
366 fn test_from_element() {
367 for isotope in DysprosiumIsotope::iter() {
368 let elem: crate::Element = isotope.into();
369 assert_eq!(elem, crate::Element::Dy);
370 }
371 }
372 #[test]
373 fn test_try_from_mass_number() {
374 for isotope in DysprosiumIsotope::iter() {
375 let mass = isotope.mass_number();
376 let iso = DysprosiumIsotope::try_from(mass).unwrap();
377 assert_eq!(iso, isotope);
378 let iso_u32 = DysprosiumIsotope::try_from(u32::from(mass)).unwrap();
379 assert_eq!(iso_u32, isotope);
380 if let Ok(mass_u8) = u8::try_from(mass) {
381 let iso_u8 = DysprosiumIsotope::try_from(mass_u8).unwrap();
382 assert_eq!(iso_u8, isotope);
383 }
384 }
385 assert!(DysprosiumIsotope::try_from(0_u16).is_err());
386 assert!(DysprosiumIsotope::try_from(1000_u16).is_err());
387 assert!(DysprosiumIsotope::try_from(0_u32).is_err());
388 assert!(DysprosiumIsotope::try_from(1000_u32).is_err());
389 assert!(DysprosiumIsotope::try_from(0_u8).is_err());
390 }
391 #[test]
392 fn test_display() {
393 for isotope in DysprosiumIsotope::iter() {
394 let s = alloc::format!("{isotope}");
395 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
396 }
397 }
398}