#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, strum :: EnumIter)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum StrontiumIsotope {
Sr73,
Sr74,
Sr75,
Sr76,
Sr77,
Sr78,
Sr79,
Sr80,
Sr81,
Sr82,
Sr83,
Sr84,
Sr85,
Sr86,
Sr87,
Sr88,
Sr89,
Sr90,
Sr91,
Sr92,
Sr93,
Sr94,
Sr95,
Sr96,
Sr97,
Sr98,
Sr99,
Sr100,
Sr101,
Sr102,
Sr103,
Sr104,
Sr105,
Sr106,
Sr107,
}
impl super::RelativeAtomicMass for StrontiumIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::Sr73 => 72.9657f64,
Self::Sr74 => 73.95617f64,
Self::Sr75 => 74.94995f64,
Self::Sr76 => 75.941763f64,
Self::Sr77 => 76.9379455f64,
Self::Sr78 => 77.93218f64,
Self::Sr79 => 78.9297077f64,
Self::Sr80 => 79.9245175f64,
Self::Sr81 => 80.9232114f64,
Self::Sr82 => 81.9183999f64,
Self::Sr83 => 82.9175544f64,
Self::Sr84 => 83.9134191f64,
Self::Sr85 => 84.912932f64,
Self::Sr86 => 85.9092606f64,
Self::Sr87 => 86.9088775f64,
Self::Sr88 => 87.9056125f64,
Self::Sr89 => 88.9074511f64,
Self::Sr90 => 89.90773f64,
Self::Sr91 => 90.9101954f64,
Self::Sr92 => 91.9110382f64,
Self::Sr93 => 92.9140242f64,
Self::Sr94 => 93.9153556f64,
Self::Sr95 => 94.9193529f64,
Self::Sr96 => 95.9217066f64,
Self::Sr97 => 96.926374f64,
Self::Sr98 => 97.9286888f64,
Self::Sr99 => 98.9328907f64,
Self::Sr100 => 99.93577f64,
Self::Sr101 => 100.940352f64,
Self::Sr102 => 101.943791f64,
Self::Sr103 => 102.94909f64,
Self::Sr104 => 103.95265f64,
Self::Sr105 => 104.95855f64,
Self::Sr106 => 105.96265f64,
Self::Sr107 => 106.96897f64,
}
}
}
impl super::ElementVariant for StrontiumIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::Sr
}
}
impl super::MassNumber for StrontiumIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::Sr73 => 73u16,
Self::Sr74 => 74u16,
Self::Sr75 => 75u16,
Self::Sr76 => 76u16,
Self::Sr77 => 77u16,
Self::Sr78 => 78u16,
Self::Sr79 => 79u16,
Self::Sr80 => 80u16,
Self::Sr81 => 81u16,
Self::Sr82 => 82u16,
Self::Sr83 => 83u16,
Self::Sr84 => 84u16,
Self::Sr85 => 85u16,
Self::Sr86 => 86u16,
Self::Sr87 => 87u16,
Self::Sr88 => 88u16,
Self::Sr89 => 89u16,
Self::Sr90 => 90u16,
Self::Sr91 => 91u16,
Self::Sr92 => 92u16,
Self::Sr93 => 93u16,
Self::Sr94 => 94u16,
Self::Sr95 => 95u16,
Self::Sr96 => 96u16,
Self::Sr97 => 97u16,
Self::Sr98 => 98u16,
Self::Sr99 => 99u16,
Self::Sr100 => 100u16,
Self::Sr101 => 101u16,
Self::Sr102 => 102u16,
Self::Sr103 => 103u16,
Self::Sr104 => 104u16,
Self::Sr105 => 105u16,
Self::Sr106 => 106u16,
Self::Sr107 => 107u16,
}
}
}
impl super::IsotopicComposition for StrontiumIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::Sr84 => Some(0.0056f64),
Self::Sr86 => Some(0.0986f64),
Self::Sr87 => Some(0.07f64),
Self::Sr88 => Some(0.8258f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for StrontiumIsotope {
fn most_abundant_isotope() -> Self {
Self::Sr88
}
}
impl From<StrontiumIsotope> for crate::Isotope {
fn from(isotope: StrontiumIsotope) -> Self {
crate::Isotope::Sr(isotope)
}
}
impl From<StrontiumIsotope> for crate::Element {
fn from(_isotope: StrontiumIsotope) -> Self {
crate::Element::Sr
}
}
impl TryFrom<u64> for StrontiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
73u64 => Ok(Self::Sr73),
74u64 => Ok(Self::Sr74),
75u64 => Ok(Self::Sr75),
76u64 => Ok(Self::Sr76),
77u64 => Ok(Self::Sr77),
78u64 => Ok(Self::Sr78),
79u64 => Ok(Self::Sr79),
80u64 => Ok(Self::Sr80),
81u64 => Ok(Self::Sr81),
82u64 => Ok(Self::Sr82),
83u64 => Ok(Self::Sr83),
84u64 => Ok(Self::Sr84),
85u64 => Ok(Self::Sr85),
86u64 => Ok(Self::Sr86),
87u64 => Ok(Self::Sr87),
88u64 => Ok(Self::Sr88),
89u64 => Ok(Self::Sr89),
90u64 => Ok(Self::Sr90),
91u64 => Ok(Self::Sr91),
92u64 => Ok(Self::Sr92),
93u64 => Ok(Self::Sr93),
94u64 => Ok(Self::Sr94),
95u64 => Ok(Self::Sr95),
96u64 => Ok(Self::Sr96),
97u64 => Ok(Self::Sr97),
98u64 => Ok(Self::Sr98),
99u64 => Ok(Self::Sr99),
100u64 => Ok(Self::Sr100),
101u64 => Ok(Self::Sr101),
102u64 => Ok(Self::Sr102),
103u64 => Ok(Self::Sr103),
104u64 => Ok(Self::Sr104),
105u64 => Ok(Self::Sr105),
106u64 => Ok(Self::Sr106),
107u64 => Ok(Self::Sr107),
_ => Err(crate::errors::Error::Isotope(crate::Element::Sr, value)),
}
}
}
impl TryFrom<u8> for StrontiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for StrontiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for StrontiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u32) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl core::fmt::Display for StrontiumIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Sr73 => write!(f, "Sr73"),
Self::Sr74 => write!(f, "Sr74"),
Self::Sr75 => write!(f, "Sr75"),
Self::Sr76 => write!(f, "Sr76"),
Self::Sr77 => write!(f, "Sr77"),
Self::Sr78 => write!(f, "Sr78"),
Self::Sr79 => write!(f, "Sr79"),
Self::Sr80 => write!(f, "Sr80"),
Self::Sr81 => write!(f, "Sr81"),
Self::Sr82 => write!(f, "Sr82"),
Self::Sr83 => write!(f, "Sr83"),
Self::Sr84 => write!(f, "Sr84"),
Self::Sr85 => write!(f, "Sr85"),
Self::Sr86 => write!(f, "Sr86"),
Self::Sr87 => write!(f, "Sr87"),
Self::Sr88 => write!(f, "Sr88"),
Self::Sr89 => write!(f, "Sr89"),
Self::Sr90 => write!(f, "Sr90"),
Self::Sr91 => write!(f, "Sr91"),
Self::Sr92 => write!(f, "Sr92"),
Self::Sr93 => write!(f, "Sr93"),
Self::Sr94 => write!(f, "Sr94"),
Self::Sr95 => write!(f, "Sr95"),
Self::Sr96 => write!(f, "Sr96"),
Self::Sr97 => write!(f, "Sr97"),
Self::Sr98 => write!(f, "Sr98"),
Self::Sr99 => write!(f, "Sr99"),
Self::Sr100 => write!(f, "Sr100"),
Self::Sr101 => write!(f, "Sr101"),
Self::Sr102 => write!(f, "Sr102"),
Self::Sr103 => write!(f, "Sr103"),
Self::Sr104 => write!(f, "Sr104"),
Self::Sr105 => write!(f, "Sr105"),
Self::Sr106 => write!(f, "Sr106"),
Self::Sr107 => write!(f, "Sr107"),
}
}
}
#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;
use super::*;
use crate::isotopes::{
ElementVariant, IsotopicComposition, MassNumber, MostAbundantIsotope, RelativeAtomicMass,
};
#[test]
fn test_relative_atomic_mass() {
for isotope in StrontiumIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in StrontiumIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::Sr, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in StrontiumIsotope::iter() {
let mass_number = isotope.mass_number();
assert!(
mass_number > 0 && mass_number < 300,
"Mass number should be reasonable for {isotope:?}"
);
}
}
#[test]
fn test_isotopic_composition() {
for isotope in StrontiumIsotope::iter() {
let comp = isotope.isotopic_composition();
if let Some(c) = comp {
assert!(
(0.0..=1.0).contains(&c),
"Composition should be between 0 and 1 for {isotope:?}"
);
}
}
}
#[test]
fn test_most_abundant() {
let most_abundant = StrontiumIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in StrontiumIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::Sr(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in StrontiumIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::Sr);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in StrontiumIsotope::iter() {
let mass = isotope.mass_number();
let iso = StrontiumIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = StrontiumIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = StrontiumIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(StrontiumIsotope::try_from(0_u16).is_err());
assert!(StrontiumIsotope::try_from(1000_u16).is_err());
assert!(StrontiumIsotope::try_from(0_u32).is_err());
assert!(StrontiumIsotope::try_from(1000_u32).is_err());
assert!(StrontiumIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in StrontiumIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}