#[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 DysprosiumIsotope {
Dy138,
Dy139,
Dy140,
Dy141,
Dy142,
Dy143,
Dy144,
Dy145,
Dy146,
Dy147,
Dy148,
Dy149,
Dy150,
Dy151,
Dy152,
Dy153,
Dy154,
Dy155,
Dy156,
Dy157,
Dy158,
Dy159,
Dy160,
Dy161,
Dy162,
Dy163,
Dy164,
Dy165,
Dy166,
Dy167,
Dy168,
Dy169,
Dy170,
Dy171,
Dy172,
Dy173,
Dy174,
Dy175,
Dy176,
}
impl super::RelativeAtomicMass for DysprosiumIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::Dy138 => 137.9625f64,
Self::Dy139 => 138.95959f64,
Self::Dy140 => 139.95402f64,
Self::Dy141 => 140.95128f64,
Self::Dy142 => 141.94619f64,
Self::Dy143 => 142.943994f64,
Self::Dy144 => 143.9392695f64,
Self::Dy145 => 144.937474f64,
Self::Dy146 => 145.9328445f64,
Self::Dy147 => 146.9310827f64,
Self::Dy148 => 147.927157f64,
Self::Dy149 => 148.927322f64,
Self::Dy150 => 149.9255933f64,
Self::Dy151 => 150.9261916f64,
Self::Dy152 => 151.9247253f64,
Self::Dy153 => 152.9257724f64,
Self::Dy154 => 153.9244293f64,
Self::Dy155 => 154.925759f64,
Self::Dy156 => 155.9242847f64,
Self::Dy157 => 156.9254707f64,
Self::Dy158 => 157.9244159f64,
Self::Dy159 => 158.925747f64,
Self::Dy160 => 159.9252046f64,
Self::Dy161 => 160.9269405f64,
Self::Dy162 => 161.9268056f64,
Self::Dy163 => 162.9287383f64,
Self::Dy164 => 163.9291819f64,
Self::Dy165 => 164.9317105f64,
Self::Dy166 => 165.9328139f64,
Self::Dy167 => 166.935661f64,
Self::Dy168 => 167.93713f64,
Self::Dy169 => 168.94031f64,
Self::Dy170 => 169.94239f64,
Self::Dy171 => 170.94612f64,
Self::Dy172 => 171.94846f64,
Self::Dy173 => 172.95283f64,
Self::Dy174 => 173.955845f64,
Self::Dy175 => 174.960569f64,
Self::Dy176 => 175.963918f64,
}
}
}
impl super::ElementVariant for DysprosiumIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::Dy
}
}
impl super::MassNumber for DysprosiumIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::Dy138 => 138u16,
Self::Dy139 => 139u16,
Self::Dy140 => 140u16,
Self::Dy141 => 141u16,
Self::Dy142 => 142u16,
Self::Dy143 => 143u16,
Self::Dy144 => 144u16,
Self::Dy145 => 145u16,
Self::Dy146 => 146u16,
Self::Dy147 => 147u16,
Self::Dy148 => 148u16,
Self::Dy149 => 149u16,
Self::Dy150 => 150u16,
Self::Dy151 => 151u16,
Self::Dy152 => 152u16,
Self::Dy153 => 153u16,
Self::Dy154 => 154u16,
Self::Dy155 => 155u16,
Self::Dy156 => 156u16,
Self::Dy157 => 157u16,
Self::Dy158 => 158u16,
Self::Dy159 => 159u16,
Self::Dy160 => 160u16,
Self::Dy161 => 161u16,
Self::Dy162 => 162u16,
Self::Dy163 => 163u16,
Self::Dy164 => 164u16,
Self::Dy165 => 165u16,
Self::Dy166 => 166u16,
Self::Dy167 => 167u16,
Self::Dy168 => 168u16,
Self::Dy169 => 169u16,
Self::Dy170 => 170u16,
Self::Dy171 => 171u16,
Self::Dy172 => 172u16,
Self::Dy173 => 173u16,
Self::Dy174 => 174u16,
Self::Dy175 => 175u16,
Self::Dy176 => 176u16,
}
}
}
impl super::IsotopicComposition for DysprosiumIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::Dy156 => Some(0.00056f64),
Self::Dy158 => Some(0.00095f64),
Self::Dy160 => Some(0.02329f64),
Self::Dy161 => Some(0.18889f64),
Self::Dy162 => Some(0.25475f64),
Self::Dy163 => Some(0.24896f64),
Self::Dy164 => Some(0.2826f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for DysprosiumIsotope {
fn most_abundant_isotope() -> Self {
Self::Dy164
}
}
impl From<DysprosiumIsotope> for crate::Isotope {
fn from(isotope: DysprosiumIsotope) -> Self {
crate::Isotope::Dy(isotope)
}
}
impl From<DysprosiumIsotope> for crate::Element {
fn from(_isotope: DysprosiumIsotope) -> Self {
crate::Element::Dy
}
}
impl TryFrom<u64> for DysprosiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
138u64 => Ok(Self::Dy138),
139u64 => Ok(Self::Dy139),
140u64 => Ok(Self::Dy140),
141u64 => Ok(Self::Dy141),
142u64 => Ok(Self::Dy142),
143u64 => Ok(Self::Dy143),
144u64 => Ok(Self::Dy144),
145u64 => Ok(Self::Dy145),
146u64 => Ok(Self::Dy146),
147u64 => Ok(Self::Dy147),
148u64 => Ok(Self::Dy148),
149u64 => Ok(Self::Dy149),
150u64 => Ok(Self::Dy150),
151u64 => Ok(Self::Dy151),
152u64 => Ok(Self::Dy152),
153u64 => Ok(Self::Dy153),
154u64 => Ok(Self::Dy154),
155u64 => Ok(Self::Dy155),
156u64 => Ok(Self::Dy156),
157u64 => Ok(Self::Dy157),
158u64 => Ok(Self::Dy158),
159u64 => Ok(Self::Dy159),
160u64 => Ok(Self::Dy160),
161u64 => Ok(Self::Dy161),
162u64 => Ok(Self::Dy162),
163u64 => Ok(Self::Dy163),
164u64 => Ok(Self::Dy164),
165u64 => Ok(Self::Dy165),
166u64 => Ok(Self::Dy166),
167u64 => Ok(Self::Dy167),
168u64 => Ok(Self::Dy168),
169u64 => Ok(Self::Dy169),
170u64 => Ok(Self::Dy170),
171u64 => Ok(Self::Dy171),
172u64 => Ok(Self::Dy172),
173u64 => Ok(Self::Dy173),
174u64 => Ok(Self::Dy174),
175u64 => Ok(Self::Dy175),
176u64 => Ok(Self::Dy176),
_ => Err(crate::errors::Error::Isotope(crate::Element::Dy, value)),
}
}
}
impl TryFrom<u8> for DysprosiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for DysprosiumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for DysprosiumIsotope {
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 DysprosiumIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Dy138 => write!(f, "Dy138"),
Self::Dy139 => write!(f, "Dy139"),
Self::Dy140 => write!(f, "Dy140"),
Self::Dy141 => write!(f, "Dy141"),
Self::Dy142 => write!(f, "Dy142"),
Self::Dy143 => write!(f, "Dy143"),
Self::Dy144 => write!(f, "Dy144"),
Self::Dy145 => write!(f, "Dy145"),
Self::Dy146 => write!(f, "Dy146"),
Self::Dy147 => write!(f, "Dy147"),
Self::Dy148 => write!(f, "Dy148"),
Self::Dy149 => write!(f, "Dy149"),
Self::Dy150 => write!(f, "Dy150"),
Self::Dy151 => write!(f, "Dy151"),
Self::Dy152 => write!(f, "Dy152"),
Self::Dy153 => write!(f, "Dy153"),
Self::Dy154 => write!(f, "Dy154"),
Self::Dy155 => write!(f, "Dy155"),
Self::Dy156 => write!(f, "Dy156"),
Self::Dy157 => write!(f, "Dy157"),
Self::Dy158 => write!(f, "Dy158"),
Self::Dy159 => write!(f, "Dy159"),
Self::Dy160 => write!(f, "Dy160"),
Self::Dy161 => write!(f, "Dy161"),
Self::Dy162 => write!(f, "Dy162"),
Self::Dy163 => write!(f, "Dy163"),
Self::Dy164 => write!(f, "Dy164"),
Self::Dy165 => write!(f, "Dy165"),
Self::Dy166 => write!(f, "Dy166"),
Self::Dy167 => write!(f, "Dy167"),
Self::Dy168 => write!(f, "Dy168"),
Self::Dy169 => write!(f, "Dy169"),
Self::Dy170 => write!(f, "Dy170"),
Self::Dy171 => write!(f, "Dy171"),
Self::Dy172 => write!(f, "Dy172"),
Self::Dy173 => write!(f, "Dy173"),
Self::Dy174 => write!(f, "Dy174"),
Self::Dy175 => write!(f, "Dy175"),
Self::Dy176 => write!(f, "Dy176"),
}
}
}
#[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 DysprosiumIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in DysprosiumIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::Dy, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in DysprosiumIsotope::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 DysprosiumIsotope::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 = DysprosiumIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in DysprosiumIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::Dy(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in DysprosiumIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::Dy);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in DysprosiumIsotope::iter() {
let mass = isotope.mass_number();
let iso = DysprosiumIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = DysprosiumIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = DysprosiumIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(DysprosiumIsotope::try_from(0_u16).is_err());
assert!(DysprosiumIsotope::try_from(1000_u16).is_err());
assert!(DysprosiumIsotope::try_from(0_u32).is_err());
assert!(DysprosiumIsotope::try_from(1000_u32).is_err());
assert!(DysprosiumIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in DysprosiumIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}