#[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 MolybdenumIsotope {
Mo81,
Mo82,
Mo83,
Mo84,
Mo85,
Mo86,
Mo87,
Mo88,
Mo89,
Mo90,
Mo91,
Mo92,
Mo93,
Mo94,
Mo95,
Mo96,
Mo97,
Mo98,
Mo99,
Mo100,
Mo101,
Mo102,
Mo103,
Mo104,
Mo105,
Mo106,
Mo107,
Mo108,
Mo109,
Mo110,
Mo111,
Mo112,
Mo113,
Mo114,
Mo115,
Mo116,
Mo117,
Mo118,
Mo119,
}
impl super::RelativeAtomicMass for MolybdenumIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::Mo81 => 80.966226f64,
Self::Mo82 => 81.956661f64,
Self::Mo83 => 82.94988f64,
Self::Mo84 => 83.94149f64,
Self::Mo85 => 84.938261f64,
Self::Mo86 => 85.9311748f64,
Self::Mo87 => 86.9281962f64,
Self::Mo88 => 87.9219678f64,
Self::Mo89 => 88.9194682f64,
Self::Mo90 => 89.9139309f64,
Self::Mo91 => 90.9117453f64,
Self::Mo92 => 91.90680796f64,
Self::Mo93 => 92.90680958f64,
Self::Mo94 => 93.9050849f64,
Self::Mo95 => 94.90583877f64,
Self::Mo96 => 95.90467612f64,
Self::Mo97 => 96.90601812f64,
Self::Mo98 => 97.90540482f64,
Self::Mo99 => 98.90770851f64,
Self::Mo100 => 99.9074718f64,
Self::Mo101 => 100.9103414f64,
Self::Mo102 => 101.9102834f64,
Self::Mo103 => 102.913079f64,
Self::Mo104 => 103.9137344f64,
Self::Mo105 => 104.916969f64,
Self::Mo106 => 105.918259f64,
Self::Mo107 => 106.922106f64,
Self::Mo108 => 107.924033f64,
Self::Mo109 => 108.928424f64,
Self::Mo110 => 109.930704f64,
Self::Mo111 => 110.935654f64,
Self::Mo112 => 111.93831f64,
Self::Mo113 => 112.94335f64,
Self::Mo114 => 113.94653f64,
Self::Mo115 => 114.95196f64,
Self::Mo116 => 115.95545f64,
Self::Mo117 => 116.96117f64,
Self::Mo118 => 117.965249f64,
Self::Mo119 => 118.971465f64,
}
}
}
impl super::ElementVariant for MolybdenumIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::Mo
}
}
impl super::MassNumber for MolybdenumIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::Mo81 => 81u16,
Self::Mo82 => 82u16,
Self::Mo83 => 83u16,
Self::Mo84 => 84u16,
Self::Mo85 => 85u16,
Self::Mo86 => 86u16,
Self::Mo87 => 87u16,
Self::Mo88 => 88u16,
Self::Mo89 => 89u16,
Self::Mo90 => 90u16,
Self::Mo91 => 91u16,
Self::Mo92 => 92u16,
Self::Mo93 => 93u16,
Self::Mo94 => 94u16,
Self::Mo95 => 95u16,
Self::Mo96 => 96u16,
Self::Mo97 => 97u16,
Self::Mo98 => 98u16,
Self::Mo99 => 99u16,
Self::Mo100 => 100u16,
Self::Mo101 => 101u16,
Self::Mo102 => 102u16,
Self::Mo103 => 103u16,
Self::Mo104 => 104u16,
Self::Mo105 => 105u16,
Self::Mo106 => 106u16,
Self::Mo107 => 107u16,
Self::Mo108 => 108u16,
Self::Mo109 => 109u16,
Self::Mo110 => 110u16,
Self::Mo111 => 111u16,
Self::Mo112 => 112u16,
Self::Mo113 => 113u16,
Self::Mo114 => 114u16,
Self::Mo115 => 115u16,
Self::Mo116 => 116u16,
Self::Mo117 => 117u16,
Self::Mo118 => 118u16,
Self::Mo119 => 119u16,
}
}
}
impl super::IsotopicComposition for MolybdenumIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::Mo92 => Some(0.1453f64),
Self::Mo94 => Some(0.0915f64),
Self::Mo95 => Some(0.1584f64),
Self::Mo96 => Some(0.1667f64),
Self::Mo97 => Some(0.096f64),
Self::Mo98 => Some(0.2439f64),
Self::Mo100 => Some(0.0982f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for MolybdenumIsotope {
fn most_abundant_isotope() -> Self {
Self::Mo98
}
}
impl From<MolybdenumIsotope> for crate::Isotope {
fn from(isotope: MolybdenumIsotope) -> Self {
crate::Isotope::Mo(isotope)
}
}
impl From<MolybdenumIsotope> for crate::Element {
fn from(_isotope: MolybdenumIsotope) -> Self {
crate::Element::Mo
}
}
impl TryFrom<u64> for MolybdenumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
81u64 => Ok(Self::Mo81),
82u64 => Ok(Self::Mo82),
83u64 => Ok(Self::Mo83),
84u64 => Ok(Self::Mo84),
85u64 => Ok(Self::Mo85),
86u64 => Ok(Self::Mo86),
87u64 => Ok(Self::Mo87),
88u64 => Ok(Self::Mo88),
89u64 => Ok(Self::Mo89),
90u64 => Ok(Self::Mo90),
91u64 => Ok(Self::Mo91),
92u64 => Ok(Self::Mo92),
93u64 => Ok(Self::Mo93),
94u64 => Ok(Self::Mo94),
95u64 => Ok(Self::Mo95),
96u64 => Ok(Self::Mo96),
97u64 => Ok(Self::Mo97),
98u64 => Ok(Self::Mo98),
99u64 => Ok(Self::Mo99),
100u64 => Ok(Self::Mo100),
101u64 => Ok(Self::Mo101),
102u64 => Ok(Self::Mo102),
103u64 => Ok(Self::Mo103),
104u64 => Ok(Self::Mo104),
105u64 => Ok(Self::Mo105),
106u64 => Ok(Self::Mo106),
107u64 => Ok(Self::Mo107),
108u64 => Ok(Self::Mo108),
109u64 => Ok(Self::Mo109),
110u64 => Ok(Self::Mo110),
111u64 => Ok(Self::Mo111),
112u64 => Ok(Self::Mo112),
113u64 => Ok(Self::Mo113),
114u64 => Ok(Self::Mo114),
115u64 => Ok(Self::Mo115),
116u64 => Ok(Self::Mo116),
117u64 => Ok(Self::Mo117),
118u64 => Ok(Self::Mo118),
119u64 => Ok(Self::Mo119),
_ => Err(crate::errors::Error::Isotope(crate::Element::Mo, value)),
}
}
}
impl TryFrom<u8> for MolybdenumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for MolybdenumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for MolybdenumIsotope {
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 MolybdenumIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Mo81 => write!(f, "Mo81"),
Self::Mo82 => write!(f, "Mo82"),
Self::Mo83 => write!(f, "Mo83"),
Self::Mo84 => write!(f, "Mo84"),
Self::Mo85 => write!(f, "Mo85"),
Self::Mo86 => write!(f, "Mo86"),
Self::Mo87 => write!(f, "Mo87"),
Self::Mo88 => write!(f, "Mo88"),
Self::Mo89 => write!(f, "Mo89"),
Self::Mo90 => write!(f, "Mo90"),
Self::Mo91 => write!(f, "Mo91"),
Self::Mo92 => write!(f, "Mo92"),
Self::Mo93 => write!(f, "Mo93"),
Self::Mo94 => write!(f, "Mo94"),
Self::Mo95 => write!(f, "Mo95"),
Self::Mo96 => write!(f, "Mo96"),
Self::Mo97 => write!(f, "Mo97"),
Self::Mo98 => write!(f, "Mo98"),
Self::Mo99 => write!(f, "Mo99"),
Self::Mo100 => write!(f, "Mo100"),
Self::Mo101 => write!(f, "Mo101"),
Self::Mo102 => write!(f, "Mo102"),
Self::Mo103 => write!(f, "Mo103"),
Self::Mo104 => write!(f, "Mo104"),
Self::Mo105 => write!(f, "Mo105"),
Self::Mo106 => write!(f, "Mo106"),
Self::Mo107 => write!(f, "Mo107"),
Self::Mo108 => write!(f, "Mo108"),
Self::Mo109 => write!(f, "Mo109"),
Self::Mo110 => write!(f, "Mo110"),
Self::Mo111 => write!(f, "Mo111"),
Self::Mo112 => write!(f, "Mo112"),
Self::Mo113 => write!(f, "Mo113"),
Self::Mo114 => write!(f, "Mo114"),
Self::Mo115 => write!(f, "Mo115"),
Self::Mo116 => write!(f, "Mo116"),
Self::Mo117 => write!(f, "Mo117"),
Self::Mo118 => write!(f, "Mo118"),
Self::Mo119 => write!(f, "Mo119"),
}
}
}
#[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 MolybdenumIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in MolybdenumIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::Mo, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in MolybdenumIsotope::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 MolybdenumIsotope::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 = MolybdenumIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in MolybdenumIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::Mo(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in MolybdenumIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::Mo);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in MolybdenumIsotope::iter() {
let mass = isotope.mass_number();
let iso = MolybdenumIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = MolybdenumIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = MolybdenumIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(MolybdenumIsotope::try_from(0_u16).is_err());
assert!(MolybdenumIsotope::try_from(1000_u16).is_err());
assert!(MolybdenumIsotope::try_from(0_u32).is_err());
assert!(MolybdenumIsotope::try_from(1000_u32).is_err());
assert!(MolybdenumIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in MolybdenumIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}