1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4pub enum StrontiumIsotope {
6 Sr73,
8 Sr74,
10 Sr75,
12 Sr76,
14 Sr77,
16 Sr78,
18 Sr79,
20 Sr80,
22 Sr81,
24 Sr82,
26 Sr83,
28 Sr84,
30 Sr85,
32 Sr86,
34 Sr87,
36 Sr88,
38 Sr89,
40 Sr90,
42 Sr91,
44 Sr92,
46 Sr93,
48 Sr94,
50 Sr95,
52 Sr96,
54 Sr97,
56 Sr98,
58 Sr99,
60 Sr100,
62 Sr101,
64 Sr102,
66 Sr103,
68 Sr104,
70 Sr105,
72 Sr106,
74 Sr107,
76}
77impl super::RelativeAtomicMass for StrontiumIsotope {
78 #[inline]
79 fn relative_atomic_mass(&self) -> f64 {
80 match self {
81 Self::Sr73 => 72.9657f64,
82 Self::Sr74 => 73.95617f64,
83 Self::Sr75 => 74.94995f64,
84 Self::Sr76 => 75.941763f64,
85 Self::Sr77 => 76.9379455f64,
86 Self::Sr78 => 77.93218f64,
87 Self::Sr79 => 78.9297077f64,
88 Self::Sr80 => 79.9245175f64,
89 Self::Sr81 => 80.9232114f64,
90 Self::Sr82 => 81.9183999f64,
91 Self::Sr83 => 82.9175544f64,
92 Self::Sr84 => 83.9134191f64,
93 Self::Sr85 => 84.912932f64,
94 Self::Sr86 => 85.9092606f64,
95 Self::Sr87 => 86.9088775f64,
96 Self::Sr88 => 87.9056125f64,
97 Self::Sr89 => 88.9074511f64,
98 Self::Sr90 => 89.90773f64,
99 Self::Sr91 => 90.9101954f64,
100 Self::Sr92 => 91.9110382f64,
101 Self::Sr93 => 92.9140242f64,
102 Self::Sr94 => 93.9153556f64,
103 Self::Sr95 => 94.9193529f64,
104 Self::Sr96 => 95.9217066f64,
105 Self::Sr97 => 96.926374f64,
106 Self::Sr98 => 97.9286888f64,
107 Self::Sr99 => 98.9328907f64,
108 Self::Sr100 => 99.93577f64,
109 Self::Sr101 => 100.940352f64,
110 Self::Sr102 => 101.943791f64,
111 Self::Sr103 => 102.94909f64,
112 Self::Sr104 => 103.95265f64,
113 Self::Sr105 => 104.95855f64,
114 Self::Sr106 => 105.96265f64,
115 Self::Sr107 => 106.96897f64,
116 }
117 }
118}
119impl super::ElementVariant for StrontiumIsotope {
120 #[inline]
121 fn element(&self) -> crate::Element {
122 crate::Element::Sr
123 }
124}
125impl super::MassNumber for StrontiumIsotope {
126 #[inline]
127 fn mass_number(&self) -> u16 {
128 match self {
129 Self::Sr73 => 73u16,
130 Self::Sr74 => 74u16,
131 Self::Sr75 => 75u16,
132 Self::Sr76 => 76u16,
133 Self::Sr77 => 77u16,
134 Self::Sr78 => 78u16,
135 Self::Sr79 => 79u16,
136 Self::Sr80 => 80u16,
137 Self::Sr81 => 81u16,
138 Self::Sr82 => 82u16,
139 Self::Sr83 => 83u16,
140 Self::Sr84 => 84u16,
141 Self::Sr85 => 85u16,
142 Self::Sr86 => 86u16,
143 Self::Sr87 => 87u16,
144 Self::Sr88 => 88u16,
145 Self::Sr89 => 89u16,
146 Self::Sr90 => 90u16,
147 Self::Sr91 => 91u16,
148 Self::Sr92 => 92u16,
149 Self::Sr93 => 93u16,
150 Self::Sr94 => 94u16,
151 Self::Sr95 => 95u16,
152 Self::Sr96 => 96u16,
153 Self::Sr97 => 97u16,
154 Self::Sr98 => 98u16,
155 Self::Sr99 => 99u16,
156 Self::Sr100 => 100u16,
157 Self::Sr101 => 101u16,
158 Self::Sr102 => 102u16,
159 Self::Sr103 => 103u16,
160 Self::Sr104 => 104u16,
161 Self::Sr105 => 105u16,
162 Self::Sr106 => 106u16,
163 Self::Sr107 => 107u16,
164 }
165 }
166}
167impl super::IsotopicComposition for StrontiumIsotope {
168 #[inline]
169 fn isotopic_composition(&self) -> Option<f64> {
170 match self {
171 Self::Sr84 => Some(0.0056f64),
172 Self::Sr86 => Some(0.0986f64),
173 Self::Sr87 => Some(0.07f64),
174 Self::Sr88 => Some(0.8258f64),
175 _ => None,
176 }
177 }
178}
179impl super::MostAbundantIsotope for StrontiumIsotope {
180 fn most_abundant_isotope() -> Self {
181 Self::Sr88
182 }
183}
184impl From<StrontiumIsotope> for crate::Isotope {
185 fn from(isotope: StrontiumIsotope) -> Self {
186 crate::Isotope::Sr(isotope)
187 }
188}
189impl From<StrontiumIsotope> for crate::Element {
190 fn from(_isotope: StrontiumIsotope) -> Self {
191 crate::Element::Sr
192 }
193}
194impl TryFrom<u64> for StrontiumIsotope {
195 type Error = crate::errors::Error;
196 fn try_from(value: u64) -> Result<Self, Self::Error> {
197 match value {
198 73u64 => Ok(Self::Sr73),
199 74u64 => Ok(Self::Sr74),
200 75u64 => Ok(Self::Sr75),
201 76u64 => Ok(Self::Sr76),
202 77u64 => Ok(Self::Sr77),
203 78u64 => Ok(Self::Sr78),
204 79u64 => Ok(Self::Sr79),
205 80u64 => Ok(Self::Sr80),
206 81u64 => Ok(Self::Sr81),
207 82u64 => Ok(Self::Sr82),
208 83u64 => Ok(Self::Sr83),
209 84u64 => Ok(Self::Sr84),
210 85u64 => Ok(Self::Sr85),
211 86u64 => Ok(Self::Sr86),
212 87u64 => Ok(Self::Sr87),
213 88u64 => Ok(Self::Sr88),
214 89u64 => Ok(Self::Sr89),
215 90u64 => Ok(Self::Sr90),
216 91u64 => Ok(Self::Sr91),
217 92u64 => Ok(Self::Sr92),
218 93u64 => Ok(Self::Sr93),
219 94u64 => Ok(Self::Sr94),
220 95u64 => Ok(Self::Sr95),
221 96u64 => Ok(Self::Sr96),
222 97u64 => Ok(Self::Sr97),
223 98u64 => Ok(Self::Sr98),
224 99u64 => Ok(Self::Sr99),
225 100u64 => Ok(Self::Sr100),
226 101u64 => Ok(Self::Sr101),
227 102u64 => Ok(Self::Sr102),
228 103u64 => Ok(Self::Sr103),
229 104u64 => Ok(Self::Sr104),
230 105u64 => Ok(Self::Sr105),
231 106u64 => Ok(Self::Sr106),
232 107u64 => Ok(Self::Sr107),
233 _ => Err(crate::errors::Error::Isotope(crate::Element::Sr, value)),
234 }
235 }
236}
237impl TryFrom<u8> for StrontiumIsotope {
238 type Error = crate::errors::Error;
239 fn try_from(value: u8) -> Result<Self, Self::Error> {
240 Self::try_from(u64::from(value))
241 }
242}
243impl TryFrom<u16> for StrontiumIsotope {
244 type Error = crate::errors::Error;
245 fn try_from(value: u16) -> Result<Self, Self::Error> {
246 Self::try_from(u64::from(value))
247 }
248}
249impl TryFrom<u32> for StrontiumIsotope {
250 type Error = crate::errors::Error;
251 fn try_from(value: u32) -> Result<Self, Self::Error> {
252 Self::try_from(u64::from(value))
253 }
254}
255impl core::fmt::Display for StrontiumIsotope {
256 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
257 match self {
258 Self::Sr73 => write!(f, "Sr73"),
259 Self::Sr74 => write!(f, "Sr74"),
260 Self::Sr75 => write!(f, "Sr75"),
261 Self::Sr76 => write!(f, "Sr76"),
262 Self::Sr77 => write!(f, "Sr77"),
263 Self::Sr78 => write!(f, "Sr78"),
264 Self::Sr79 => write!(f, "Sr79"),
265 Self::Sr80 => write!(f, "Sr80"),
266 Self::Sr81 => write!(f, "Sr81"),
267 Self::Sr82 => write!(f, "Sr82"),
268 Self::Sr83 => write!(f, "Sr83"),
269 Self::Sr84 => write!(f, "Sr84"),
270 Self::Sr85 => write!(f, "Sr85"),
271 Self::Sr86 => write!(f, "Sr86"),
272 Self::Sr87 => write!(f, "Sr87"),
273 Self::Sr88 => write!(f, "Sr88"),
274 Self::Sr89 => write!(f, "Sr89"),
275 Self::Sr90 => write!(f, "Sr90"),
276 Self::Sr91 => write!(f, "Sr91"),
277 Self::Sr92 => write!(f, "Sr92"),
278 Self::Sr93 => write!(f, "Sr93"),
279 Self::Sr94 => write!(f, "Sr94"),
280 Self::Sr95 => write!(f, "Sr95"),
281 Self::Sr96 => write!(f, "Sr96"),
282 Self::Sr97 => write!(f, "Sr97"),
283 Self::Sr98 => write!(f, "Sr98"),
284 Self::Sr99 => write!(f, "Sr99"),
285 Self::Sr100 => write!(f, "Sr100"),
286 Self::Sr101 => write!(f, "Sr101"),
287 Self::Sr102 => write!(f, "Sr102"),
288 Self::Sr103 => write!(f, "Sr103"),
289 Self::Sr104 => write!(f, "Sr104"),
290 Self::Sr105 => write!(f, "Sr105"),
291 Self::Sr106 => write!(f, "Sr106"),
292 Self::Sr107 => write!(f, "Sr107"),
293 }
294 }
295}
296#[cfg(test)]
297mod tests {
298 use strum::IntoEnumIterator;
299
300 use super::*;
301 use crate::isotopes::{
302 ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
303 };
304 #[test]
305 fn test_relative_atomic_mass() {
306 for isotope in StrontiumIsotope::iter() {
307 let mass = isotope.relative_atomic_mass();
308 assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
309 }
310 }
311 #[test]
312 fn test_element() {
313 for isotope in StrontiumIsotope::iter() {
314 let element = isotope.element();
315 assert_eq!(element, crate::Element::Sr, "Element should be correct for {isotope:?}");
316 }
317 }
318 #[test]
319 fn test_mass_number() {
320 for isotope in StrontiumIsotope::iter() {
321 let mass_number = isotope.mass_number();
322 assert!(
323 mass_number > 0 && mass_number < 300,
324 "Mass number should be reasonable for {isotope:?}"
325 );
326 }
327 }
328 #[test]
329 fn test_isotopic_composition() {
330 for isotope in StrontiumIsotope::iter() {
331 let comp = isotope.isotopic_composition();
332 if let Some(c) = comp {
333 assert!(
334 (0.0..=1.0).contains(&c),
335 "Composition should be between 0 and 1 for {isotope:?}"
336 );
337 }
338 }
339 }
340 #[test]
341 fn test_most_abundant() {
342 let most_abundant = StrontiumIsotope::most_abundant_isotope();
343 let _ = most_abundant.relative_atomic_mass();
344 }
345 #[test]
346 fn test_from_isotope() {
347 for isotope in StrontiumIsotope::iter() {
348 let iso: crate::Isotope = isotope.into();
349 match iso {
350 crate::Isotope::Sr(i) => assert_eq!(i, isotope),
351 _ => panic!("Wrong isotope type"),
352 }
353 }
354 }
355 #[test]
356 fn test_from_element() {
357 for isotope in StrontiumIsotope::iter() {
358 let elem: crate::Element = isotope.into();
359 assert_eq!(elem, crate::Element::Sr);
360 }
361 }
362 #[test]
363 fn test_try_from_mass_number() {
364 for isotope in StrontiumIsotope::iter() {
365 let mass = isotope.mass_number();
366 let iso = StrontiumIsotope::try_from(mass).unwrap();
367 assert_eq!(iso, isotope);
368 let iso_u32 = StrontiumIsotope::try_from(u32::from(mass)).unwrap();
369 assert_eq!(iso_u32, isotope);
370 if let Ok(mass_u8) = u8::try_from(mass) {
371 let iso_u8 = StrontiumIsotope::try_from(mass_u8).unwrap();
372 assert_eq!(iso_u8, isotope);
373 }
374 }
375 assert!(StrontiumIsotope::try_from(0_u16).is_err());
376 assert!(StrontiumIsotope::try_from(1000_u16).is_err());
377 assert!(StrontiumIsotope::try_from(0_u32).is_err());
378 assert!(StrontiumIsotope::try_from(1000_u32).is_err());
379 assert!(StrontiumIsotope::try_from(0_u8).is_err());
380 }
381 #[test]
382 fn test_display() {
383 for isotope in StrontiumIsotope::iter() {
384 let s = alloc::format!("{isotope}");
385 assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
386 }
387 }
388}