#[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 KryptonIsotope {
Kr67,
Kr68,
Kr69,
Kr70,
Kr71,
Kr72,
Kr73,
Kr74,
Kr75,
Kr76,
Kr77,
Kr78,
Kr79,
Kr80,
Kr81,
Kr82,
Kr83,
Kr84,
Kr85,
Kr86,
Kr87,
Kr88,
Kr89,
Kr90,
Kr91,
Kr92,
Kr93,
Kr94,
Kr95,
Kr96,
Kr97,
Kr98,
Kr99,
Kr100,
Kr101,
}
impl super::RelativeAtomicMass for KryptonIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::Kr67 => 66.983305f64,
Self::Kr68 => 67.972489f64,
Self::Kr69 => 68.96518f64,
Self::Kr70 => 69.95604f64,
Self::Kr71 => 70.95027f64,
Self::Kr72 => 71.9420924f64,
Self::Kr73 => 72.9392892f64,
Self::Kr74 => 73.933084f64,
Self::Kr75 => 74.9309457f64,
Self::Kr76 => 75.9259103f64,
Self::Kr77 => 76.92467f64,
Self::Kr78 => 77.92036494f64,
Self::Kr79 => 78.9200829f64,
Self::Kr80 => 79.91637808f64,
Self::Kr81 => 80.9165912f64,
Self::Kr82 => 81.91348273f64,
Self::Kr83 => 82.91412716f64,
Self::Kr84 => 83.9114977282f64,
Self::Kr85 => 84.9125273f64,
Self::Kr86 => 85.9106106269f64,
Self::Kr87 => 86.91335476f64,
Self::Kr88 => 87.9144479f64,
Self::Kr89 => 88.9178355f64,
Self::Kr90 => 89.9195279f64,
Self::Kr91 => 90.9238063f64,
Self::Kr92 => 91.9261731f64,
Self::Kr93 => 92.9311472f64,
Self::Kr94 => 93.93414f64,
Self::Kr95 => 94.939711f64,
Self::Kr96 => 95.943017f64,
Self::Kr97 => 96.94909f64,
Self::Kr98 => 97.95243f64,
Self::Kr99 => 98.95839f64,
Self::Kr100 => 99.96237f64,
Self::Kr101 => 100.96873f64,
}
}
}
impl super::ElementVariant for KryptonIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::Kr
}
}
impl super::MassNumber for KryptonIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::Kr67 => 67u16,
Self::Kr68 => 68u16,
Self::Kr69 => 69u16,
Self::Kr70 => 70u16,
Self::Kr71 => 71u16,
Self::Kr72 => 72u16,
Self::Kr73 => 73u16,
Self::Kr74 => 74u16,
Self::Kr75 => 75u16,
Self::Kr76 => 76u16,
Self::Kr77 => 77u16,
Self::Kr78 => 78u16,
Self::Kr79 => 79u16,
Self::Kr80 => 80u16,
Self::Kr81 => 81u16,
Self::Kr82 => 82u16,
Self::Kr83 => 83u16,
Self::Kr84 => 84u16,
Self::Kr85 => 85u16,
Self::Kr86 => 86u16,
Self::Kr87 => 87u16,
Self::Kr88 => 88u16,
Self::Kr89 => 89u16,
Self::Kr90 => 90u16,
Self::Kr91 => 91u16,
Self::Kr92 => 92u16,
Self::Kr93 => 93u16,
Self::Kr94 => 94u16,
Self::Kr95 => 95u16,
Self::Kr96 => 96u16,
Self::Kr97 => 97u16,
Self::Kr98 => 98u16,
Self::Kr99 => 99u16,
Self::Kr100 => 100u16,
Self::Kr101 => 101u16,
}
}
}
impl super::IsotopicComposition for KryptonIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::Kr78 => Some(0.00355f64),
Self::Kr80 => Some(0.02286f64),
Self::Kr82 => Some(0.11593f64),
Self::Kr83 => Some(0.115f64),
Self::Kr84 => Some(0.56987f64),
Self::Kr86 => Some(0.17279f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for KryptonIsotope {
fn most_abundant_isotope() -> Self {
Self::Kr84
}
}
impl From<KryptonIsotope> for crate::Isotope {
fn from(isotope: KryptonIsotope) -> Self {
crate::Isotope::Kr(isotope)
}
}
impl From<KryptonIsotope> for crate::Element {
fn from(_isotope: KryptonIsotope) -> Self {
crate::Element::Kr
}
}
impl TryFrom<u64> for KryptonIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
67u64 => Ok(Self::Kr67),
68u64 => Ok(Self::Kr68),
69u64 => Ok(Self::Kr69),
70u64 => Ok(Self::Kr70),
71u64 => Ok(Self::Kr71),
72u64 => Ok(Self::Kr72),
73u64 => Ok(Self::Kr73),
74u64 => Ok(Self::Kr74),
75u64 => Ok(Self::Kr75),
76u64 => Ok(Self::Kr76),
77u64 => Ok(Self::Kr77),
78u64 => Ok(Self::Kr78),
79u64 => Ok(Self::Kr79),
80u64 => Ok(Self::Kr80),
81u64 => Ok(Self::Kr81),
82u64 => Ok(Self::Kr82),
83u64 => Ok(Self::Kr83),
84u64 => Ok(Self::Kr84),
85u64 => Ok(Self::Kr85),
86u64 => Ok(Self::Kr86),
87u64 => Ok(Self::Kr87),
88u64 => Ok(Self::Kr88),
89u64 => Ok(Self::Kr89),
90u64 => Ok(Self::Kr90),
91u64 => Ok(Self::Kr91),
92u64 => Ok(Self::Kr92),
93u64 => Ok(Self::Kr93),
94u64 => Ok(Self::Kr94),
95u64 => Ok(Self::Kr95),
96u64 => Ok(Self::Kr96),
97u64 => Ok(Self::Kr97),
98u64 => Ok(Self::Kr98),
99u64 => Ok(Self::Kr99),
100u64 => Ok(Self::Kr100),
101u64 => Ok(Self::Kr101),
_ => Err(crate::errors::Error::Isotope(crate::Element::Kr, value)),
}
}
}
impl TryFrom<u8> for KryptonIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for KryptonIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for KryptonIsotope {
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 KryptonIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Kr67 => write!(f, "Kr67"),
Self::Kr68 => write!(f, "Kr68"),
Self::Kr69 => write!(f, "Kr69"),
Self::Kr70 => write!(f, "Kr70"),
Self::Kr71 => write!(f, "Kr71"),
Self::Kr72 => write!(f, "Kr72"),
Self::Kr73 => write!(f, "Kr73"),
Self::Kr74 => write!(f, "Kr74"),
Self::Kr75 => write!(f, "Kr75"),
Self::Kr76 => write!(f, "Kr76"),
Self::Kr77 => write!(f, "Kr77"),
Self::Kr78 => write!(f, "Kr78"),
Self::Kr79 => write!(f, "Kr79"),
Self::Kr80 => write!(f, "Kr80"),
Self::Kr81 => write!(f, "Kr81"),
Self::Kr82 => write!(f, "Kr82"),
Self::Kr83 => write!(f, "Kr83"),
Self::Kr84 => write!(f, "Kr84"),
Self::Kr85 => write!(f, "Kr85"),
Self::Kr86 => write!(f, "Kr86"),
Self::Kr87 => write!(f, "Kr87"),
Self::Kr88 => write!(f, "Kr88"),
Self::Kr89 => write!(f, "Kr89"),
Self::Kr90 => write!(f, "Kr90"),
Self::Kr91 => write!(f, "Kr91"),
Self::Kr92 => write!(f, "Kr92"),
Self::Kr93 => write!(f, "Kr93"),
Self::Kr94 => write!(f, "Kr94"),
Self::Kr95 => write!(f, "Kr95"),
Self::Kr96 => write!(f, "Kr96"),
Self::Kr97 => write!(f, "Kr97"),
Self::Kr98 => write!(f, "Kr98"),
Self::Kr99 => write!(f, "Kr99"),
Self::Kr100 => write!(f, "Kr100"),
Self::Kr101 => write!(f, "Kr101"),
}
}
}
#[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 KryptonIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in KryptonIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::Kr, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in KryptonIsotope::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 KryptonIsotope::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 = KryptonIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in KryptonIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::Kr(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in KryptonIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::Kr);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in KryptonIsotope::iter() {
let mass = isotope.mass_number();
let iso = KryptonIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = KryptonIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = KryptonIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(KryptonIsotope::try_from(0_u16).is_err());
assert!(KryptonIsotope::try_from(1000_u16).is_err());
assert!(KryptonIsotope::try_from(0_u32).is_err());
assert!(KryptonIsotope::try_from(1000_u32).is_err());
assert!(KryptonIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in KryptonIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}