#[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 UraniumIsotope {
U215,
U216,
U217,
U218,
U219,
U221,
U222,
U223,
U224,
U225,
U226,
U227,
U228,
U229,
U230,
U231,
U232,
U233,
U234,
U235,
U236,
U237,
U238,
U239,
U240,
U241,
U242,
U243,
}
impl super::RelativeAtomicMass for UraniumIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::U215 => 215.026719774f64,
Self::U216 => 216.024762829f64,
Self::U217 => 217.02466f64,
Self::U218 => 218.023523f64,
Self::U219 => 219.024999f64,
Self::U221 => 221.02628f64,
Self::U222 => 222.026f64,
Self::U223 => 223.027739f64,
Self::U224 => 224.027605f64,
Self::U225 => 225.029391f64,
Self::U226 => 226.029339f64,
Self::U227 => 227.031157f64,
Self::U228 => 228.031371f64,
Self::U229 => 229.0335063f64,
Self::U230 => 230.0339401f64,
Self::U231 => 231.0362939f64,
Self::U232 => 232.0371563f64,
Self::U233 => 233.0396355f64,
Self::U234 => 234.0409523f64,
Self::U235 => 235.0439301f64,
Self::U236 => 236.0455682f64,
Self::U237 => 237.0487304f64,
Self::U238 => 238.0507884f64,
Self::U239 => 239.0542935f64,
Self::U240 => 240.0565934f64,
Self::U241 => 241.06033f64,
Self::U242 => 242.06293f64,
Self::U243 => 243.06699f64,
}
}
}
impl super::ElementVariant for UraniumIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::U
}
}
impl super::MassNumber for UraniumIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::U215 => 215u16,
Self::U216 => 216u16,
Self::U217 => 217u16,
Self::U218 => 218u16,
Self::U219 => 219u16,
Self::U221 => 221u16,
Self::U222 => 222u16,
Self::U223 => 223u16,
Self::U224 => 224u16,
Self::U225 => 225u16,
Self::U226 => 226u16,
Self::U227 => 227u16,
Self::U228 => 228u16,
Self::U229 => 229u16,
Self::U230 => 230u16,
Self::U231 => 231u16,
Self::U232 => 232u16,
Self::U233 => 233u16,
Self::U234 => 234u16,
Self::U235 => 235u16,
Self::U236 => 236u16,
Self::U237 => 237u16,
Self::U238 => 238u16,
Self::U239 => 239u16,
Self::U240 => 240u16,
Self::U241 => 241u16,
Self::U242 => 242u16,
Self::U243 => 243u16,
}
}
}
impl super::IsotopicComposition for UraniumIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::U234 => Some(0.000054f64),
Self::U235 => Some(0.007204f64),
Self::U238 => Some(0.992742f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for UraniumIsotope {
fn most_abundant_isotope() -> Self {
Self::U238
}
}
impl From<UraniumIsotope> for crate::Isotope {
fn from(isotope: UraniumIsotope) -> Self {
crate::Isotope::U(isotope)
}
}
impl From<UraniumIsotope> for crate::Element {
fn from(_isotope: UraniumIsotope) -> Self {
crate::Element::U
}
}
impl TryFrom<u64> for UraniumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
215u64 => Ok(Self::U215),
216u64 => Ok(Self::U216),
217u64 => Ok(Self::U217),
218u64 => Ok(Self::U218),
219u64 => Ok(Self::U219),
221u64 => Ok(Self::U221),
222u64 => Ok(Self::U222),
223u64 => Ok(Self::U223),
224u64 => Ok(Self::U224),
225u64 => Ok(Self::U225),
226u64 => Ok(Self::U226),
227u64 => Ok(Self::U227),
228u64 => Ok(Self::U228),
229u64 => Ok(Self::U229),
230u64 => Ok(Self::U230),
231u64 => Ok(Self::U231),
232u64 => Ok(Self::U232),
233u64 => Ok(Self::U233),
234u64 => Ok(Self::U234),
235u64 => Ok(Self::U235),
236u64 => Ok(Self::U236),
237u64 => Ok(Self::U237),
238u64 => Ok(Self::U238),
239u64 => Ok(Self::U239),
240u64 => Ok(Self::U240),
241u64 => Ok(Self::U241),
242u64 => Ok(Self::U242),
243u64 => Ok(Self::U243),
_ => Err(crate::errors::Error::Isotope(crate::Element::U, value)),
}
}
}
impl TryFrom<u8> for UraniumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for UraniumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for UraniumIsotope {
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 UraniumIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::U215 => write!(f, "U215"),
Self::U216 => write!(f, "U216"),
Self::U217 => write!(f, "U217"),
Self::U218 => write!(f, "U218"),
Self::U219 => write!(f, "U219"),
Self::U221 => write!(f, "U221"),
Self::U222 => write!(f, "U222"),
Self::U223 => write!(f, "U223"),
Self::U224 => write!(f, "U224"),
Self::U225 => write!(f, "U225"),
Self::U226 => write!(f, "U226"),
Self::U227 => write!(f, "U227"),
Self::U228 => write!(f, "U228"),
Self::U229 => write!(f, "U229"),
Self::U230 => write!(f, "U230"),
Self::U231 => write!(f, "U231"),
Self::U232 => write!(f, "U232"),
Self::U233 => write!(f, "U233"),
Self::U234 => write!(f, "U234"),
Self::U235 => write!(f, "U235"),
Self::U236 => write!(f, "U236"),
Self::U237 => write!(f, "U237"),
Self::U238 => write!(f, "U238"),
Self::U239 => write!(f, "U239"),
Self::U240 => write!(f, "U240"),
Self::U241 => write!(f, "U241"),
Self::U242 => write!(f, "U242"),
Self::U243 => write!(f, "U243"),
}
}
}
#[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 UraniumIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in UraniumIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::U, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in UraniumIsotope::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 UraniumIsotope::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 = UraniumIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in UraniumIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::U(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in UraniumIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::U);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in UraniumIsotope::iter() {
let mass = isotope.mass_number();
let iso = UraniumIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = UraniumIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = UraniumIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(UraniumIsotope::try_from(0_u16).is_err());
assert!(UraniumIsotope::try_from(1000_u16).is_err());
assert!(UraniumIsotope::try_from(0_u32).is_err());
assert!(UraniumIsotope::try_from(1000_u32).is_err());
assert!(UraniumIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in UraniumIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}