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