#[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))]
#[cfg_attr(feature = "mem_size", derive(mem_dbg::MemSize))]
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg))]
#[cfg_attr(feature = "mem_size", mem_size(flat))]
pub enum SeleniumIsotope {
Se63,
Se64,
Se65,
Se66,
Se67,
Se68,
Se69,
Se70,
Se71,
Se72,
Se73,
Se74,
Se75,
Se76,
Se77,
Se78,
Se79,
Se80,
Se81,
Se82,
Se83,
Se84,
Se85,
Se86,
Se87,
Se88,
Se89,
Se90,
Se91,
Se92,
Se93,
Se94,
Se95,
}
impl super::RelativeAtomicMass for SeleniumIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::Se63 => 62.981911f64,
Self::Se64 => 63.97109f64,
Self::Se65 => 64.9644f64,
Self::Se66 => 65.95559f64,
Self::Se67 => 66.949994f64,
Self::Se68 => 67.94182524f64,
Self::Se69 => 68.9394148f64,
Self::Se70 => 69.9335155f64,
Self::Se71 => 70.9322094f64,
Self::Se72 => 71.9271405f64,
Self::Se73 => 72.9267549f64,
Self::Se74 => 73.922475934f64,
Self::Se75 => 74.92252287f64,
Self::Se76 => 75.919213704f64,
Self::Se77 => 76.919914154f64,
Self::Se78 => 77.91730928f64,
Self::Se79 => 78.91849929f64,
Self::Se80 => 79.9165218f64,
Self::Se81 => 80.917993f64,
Self::Se82 => 81.9166995f64,
Self::Se83 => 82.9191186f64,
Self::Se84 => 83.9184668f64,
Self::Se85 => 84.9222608f64,
Self::Se86 => 85.9243117f64,
Self::Se87 => 86.9286886f64,
Self::Se88 => 87.9314175f64,
Self::Se89 => 88.9366691f64,
Self::Se90 => 89.9401f64,
Self::Se91 => 90.94596f64,
Self::Se92 => 91.94984f64,
Self::Se93 => 92.95629f64,
Self::Se94 => 93.96049f64,
Self::Se95 => 94.9673f64,
}
}
}
impl super::ElementVariant for SeleniumIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::Se
}
}
impl super::MassNumber for SeleniumIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::Se63 => 63u16,
Self::Se64 => 64u16,
Self::Se65 => 65u16,
Self::Se66 => 66u16,
Self::Se67 => 67u16,
Self::Se68 => 68u16,
Self::Se69 => 69u16,
Self::Se70 => 70u16,
Self::Se71 => 71u16,
Self::Se72 => 72u16,
Self::Se73 => 73u16,
Self::Se74 => 74u16,
Self::Se75 => 75u16,
Self::Se76 => 76u16,
Self::Se77 => 77u16,
Self::Se78 => 78u16,
Self::Se79 => 79u16,
Self::Se80 => 80u16,
Self::Se81 => 81u16,
Self::Se82 => 82u16,
Self::Se83 => 83u16,
Self::Se84 => 84u16,
Self::Se85 => 85u16,
Self::Se86 => 86u16,
Self::Se87 => 87u16,
Self::Se88 => 88u16,
Self::Se89 => 89u16,
Self::Se90 => 90u16,
Self::Se91 => 91u16,
Self::Se92 => 92u16,
Self::Se93 => 93u16,
Self::Se94 => 94u16,
Self::Se95 => 95u16,
}
}
}
impl super::IsotopicComposition for SeleniumIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::Se74 => Some(0.0089f64),
Self::Se76 => Some(0.0937f64),
Self::Se77 => Some(0.0763f64),
Self::Se78 => Some(0.2377f64),
Self::Se80 => Some(0.4961f64),
Self::Se82 => Some(0.0873f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for SeleniumIsotope {
fn most_abundant_isotope() -> Self {
Self::Se80
}
}
impl From<SeleniumIsotope> for crate::Isotope {
fn from(isotope: SeleniumIsotope) -> Self {
crate::Isotope::Se(isotope)
}
}
impl From<SeleniumIsotope> for crate::Element {
fn from(_isotope: SeleniumIsotope) -> Self {
crate::Element::Se
}
}
impl TryFrom<u64> for SeleniumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
63u64 => Ok(Self::Se63),
64u64 => Ok(Self::Se64),
65u64 => Ok(Self::Se65),
66u64 => Ok(Self::Se66),
67u64 => Ok(Self::Se67),
68u64 => Ok(Self::Se68),
69u64 => Ok(Self::Se69),
70u64 => Ok(Self::Se70),
71u64 => Ok(Self::Se71),
72u64 => Ok(Self::Se72),
73u64 => Ok(Self::Se73),
74u64 => Ok(Self::Se74),
75u64 => Ok(Self::Se75),
76u64 => Ok(Self::Se76),
77u64 => Ok(Self::Se77),
78u64 => Ok(Self::Se78),
79u64 => Ok(Self::Se79),
80u64 => Ok(Self::Se80),
81u64 => Ok(Self::Se81),
82u64 => Ok(Self::Se82),
83u64 => Ok(Self::Se83),
84u64 => Ok(Self::Se84),
85u64 => Ok(Self::Se85),
86u64 => Ok(Self::Se86),
87u64 => Ok(Self::Se87),
88u64 => Ok(Self::Se88),
89u64 => Ok(Self::Se89),
90u64 => Ok(Self::Se90),
91u64 => Ok(Self::Se91),
92u64 => Ok(Self::Se92),
93u64 => Ok(Self::Se93),
94u64 => Ok(Self::Se94),
95u64 => Ok(Self::Se95),
_ => Err(crate::errors::Error::Isotope(crate::Element::Se, value)),
}
}
}
impl TryFrom<u8> for SeleniumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for SeleniumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for SeleniumIsotope {
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 SeleniumIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Se63 => write!(f, "Se63"),
Self::Se64 => write!(f, "Se64"),
Self::Se65 => write!(f, "Se65"),
Self::Se66 => write!(f, "Se66"),
Self::Se67 => write!(f, "Se67"),
Self::Se68 => write!(f, "Se68"),
Self::Se69 => write!(f, "Se69"),
Self::Se70 => write!(f, "Se70"),
Self::Se71 => write!(f, "Se71"),
Self::Se72 => write!(f, "Se72"),
Self::Se73 => write!(f, "Se73"),
Self::Se74 => write!(f, "Se74"),
Self::Se75 => write!(f, "Se75"),
Self::Se76 => write!(f, "Se76"),
Self::Se77 => write!(f, "Se77"),
Self::Se78 => write!(f, "Se78"),
Self::Se79 => write!(f, "Se79"),
Self::Se80 => write!(f, "Se80"),
Self::Se81 => write!(f, "Se81"),
Self::Se82 => write!(f, "Se82"),
Self::Se83 => write!(f, "Se83"),
Self::Se84 => write!(f, "Se84"),
Self::Se85 => write!(f, "Se85"),
Self::Se86 => write!(f, "Se86"),
Self::Se87 => write!(f, "Se87"),
Self::Se88 => write!(f, "Se88"),
Self::Se89 => write!(f, "Se89"),
Self::Se90 => write!(f, "Se90"),
Self::Se91 => write!(f, "Se91"),
Self::Se92 => write!(f, "Se92"),
Self::Se93 => write!(f, "Se93"),
Self::Se94 => write!(f, "Se94"),
Self::Se95 => write!(f, "Se95"),
}
}
}
#[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 SeleniumIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in SeleniumIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::Se, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in SeleniumIsotope::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 SeleniumIsotope::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 = SeleniumIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in SeleniumIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::Se(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in SeleniumIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::Se);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in SeleniumIsotope::iter() {
let mass = isotope.mass_number();
let iso = SeleniumIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = SeleniumIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = SeleniumIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(SeleniumIsotope::try_from(0_u16).is_err());
assert!(SeleniumIsotope::try_from(1000_u16).is_err());
assert!(SeleniumIsotope::try_from(0_u32).is_err());
assert!(SeleniumIsotope::try_from(1000_u32).is_err());
assert!(SeleniumIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in SeleniumIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}