#[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 PlatinumIsotope {
Pt165,
Pt166,
Pt167,
Pt168,
Pt169,
Pt170,
Pt171,
Pt172,
Pt173,
Pt174,
Pt175,
Pt176,
Pt177,
Pt178,
Pt179,
Pt180,
Pt181,
Pt182,
Pt183,
Pt184,
Pt185,
Pt186,
Pt187,
Pt188,
Pt189,
Pt190,
Pt191,
Pt192,
Pt193,
Pt194,
Pt195,
Pt196,
Pt197,
Pt198,
Pt199,
Pt200,
Pt201,
Pt202,
Pt203,
Pt204,
Pt205,
Pt206,
Pt207,
Pt208,
}
impl super::RelativeAtomicMass for PlatinumIsotope {
#[inline]
fn relative_atomic_mass(&self) -> f64 {
match self {
Self::Pt165 => 164.999658f64,
Self::Pt166 => 165.99486f64,
Self::Pt167 => 166.99269f64,
Self::Pt168 => 167.98813f64,
Self::Pt169 => 168.98657f64,
Self::Pt170 => 169.982496f64,
Self::Pt171 => 170.981245f64,
Self::Pt172 => 171.977351f64,
Self::Pt173 => 172.976443f64,
Self::Pt174 => 173.97282f64,
Self::Pt175 => 174.97241f64,
Self::Pt176 => 175.968938f64,
Self::Pt177 => 176.96847f64,
Self::Pt178 => 177.96565f64,
Self::Pt179 => 178.965359f64,
Self::Pt180 => 179.963032f64,
Self::Pt181 => 180.963098f64,
Self::Pt182 => 181.961172f64,
Self::Pt183 => 182.961597f64,
Self::Pt184 => 183.959915f64,
Self::Pt185 => 184.960614f64,
Self::Pt186 => 185.959351f64,
Self::Pt187 => 186.960617f64,
Self::Pt188 => 187.9593889f64,
Self::Pt189 => 188.960831f64,
Self::Pt190 => 189.9599297f64,
Self::Pt191 => 190.9616729f64,
Self::Pt192 => 191.9610387f64,
Self::Pt193 => 192.9629824f64,
Self::Pt194 => 193.9626809f64,
Self::Pt195 => 194.9647917f64,
Self::Pt196 => 195.96495209f64,
Self::Pt197 => 196.96734069f64,
Self::Pt198 => 197.9678949f64,
Self::Pt199 => 198.9705952f64,
Self::Pt200 => 199.971443f64,
Self::Pt201 => 200.974513f64,
Self::Pt202 => 201.975639f64,
Self::Pt203 => 202.97893f64,
Self::Pt204 => 203.98076f64,
Self::Pt205 => 204.98608f64,
Self::Pt206 => 205.98966f64,
Self::Pt207 => 206.995556f64,
Self::Pt208 => 207.999463f64,
}
}
}
impl super::ElementVariant for PlatinumIsotope {
#[inline]
fn element(&self) -> crate::Element {
crate::Element::Pt
}
}
impl super::MassNumber for PlatinumIsotope {
#[inline]
fn mass_number(&self) -> u16 {
match self {
Self::Pt165 => 165u16,
Self::Pt166 => 166u16,
Self::Pt167 => 167u16,
Self::Pt168 => 168u16,
Self::Pt169 => 169u16,
Self::Pt170 => 170u16,
Self::Pt171 => 171u16,
Self::Pt172 => 172u16,
Self::Pt173 => 173u16,
Self::Pt174 => 174u16,
Self::Pt175 => 175u16,
Self::Pt176 => 176u16,
Self::Pt177 => 177u16,
Self::Pt178 => 178u16,
Self::Pt179 => 179u16,
Self::Pt180 => 180u16,
Self::Pt181 => 181u16,
Self::Pt182 => 182u16,
Self::Pt183 => 183u16,
Self::Pt184 => 184u16,
Self::Pt185 => 185u16,
Self::Pt186 => 186u16,
Self::Pt187 => 187u16,
Self::Pt188 => 188u16,
Self::Pt189 => 189u16,
Self::Pt190 => 190u16,
Self::Pt191 => 191u16,
Self::Pt192 => 192u16,
Self::Pt193 => 193u16,
Self::Pt194 => 194u16,
Self::Pt195 => 195u16,
Self::Pt196 => 196u16,
Self::Pt197 => 197u16,
Self::Pt198 => 198u16,
Self::Pt199 => 199u16,
Self::Pt200 => 200u16,
Self::Pt201 => 201u16,
Self::Pt202 => 202u16,
Self::Pt203 => 203u16,
Self::Pt204 => 204u16,
Self::Pt205 => 205u16,
Self::Pt206 => 206u16,
Self::Pt207 => 207u16,
Self::Pt208 => 208u16,
}
}
}
impl super::IsotopicComposition for PlatinumIsotope {
#[inline]
fn isotopic_composition(&self) -> Option<f64> {
match self {
Self::Pt190 => Some(0.00012f64),
Self::Pt192 => Some(0.00782f64),
Self::Pt194 => Some(0.3286f64),
Self::Pt195 => Some(0.3378f64),
Self::Pt196 => Some(0.2521f64),
Self::Pt198 => Some(0.07356f64),
_ => None,
}
}
}
impl super::MostAbundantIsotope for PlatinumIsotope {
fn most_abundant_isotope() -> Self {
Self::Pt195
}
}
impl From<PlatinumIsotope> for crate::Isotope {
fn from(isotope: PlatinumIsotope) -> Self {
crate::Isotope::Pt(isotope)
}
}
impl From<PlatinumIsotope> for crate::Element {
fn from(_isotope: PlatinumIsotope) -> Self {
crate::Element::Pt
}
}
impl TryFrom<u64> for PlatinumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
165u64 => Ok(Self::Pt165),
166u64 => Ok(Self::Pt166),
167u64 => Ok(Self::Pt167),
168u64 => Ok(Self::Pt168),
169u64 => Ok(Self::Pt169),
170u64 => Ok(Self::Pt170),
171u64 => Ok(Self::Pt171),
172u64 => Ok(Self::Pt172),
173u64 => Ok(Self::Pt173),
174u64 => Ok(Self::Pt174),
175u64 => Ok(Self::Pt175),
176u64 => Ok(Self::Pt176),
177u64 => Ok(Self::Pt177),
178u64 => Ok(Self::Pt178),
179u64 => Ok(Self::Pt179),
180u64 => Ok(Self::Pt180),
181u64 => Ok(Self::Pt181),
182u64 => Ok(Self::Pt182),
183u64 => Ok(Self::Pt183),
184u64 => Ok(Self::Pt184),
185u64 => Ok(Self::Pt185),
186u64 => Ok(Self::Pt186),
187u64 => Ok(Self::Pt187),
188u64 => Ok(Self::Pt188),
189u64 => Ok(Self::Pt189),
190u64 => Ok(Self::Pt190),
191u64 => Ok(Self::Pt191),
192u64 => Ok(Self::Pt192),
193u64 => Ok(Self::Pt193),
194u64 => Ok(Self::Pt194),
195u64 => Ok(Self::Pt195),
196u64 => Ok(Self::Pt196),
197u64 => Ok(Self::Pt197),
198u64 => Ok(Self::Pt198),
199u64 => Ok(Self::Pt199),
200u64 => Ok(Self::Pt200),
201u64 => Ok(Self::Pt201),
202u64 => Ok(Self::Pt202),
203u64 => Ok(Self::Pt203),
204u64 => Ok(Self::Pt204),
205u64 => Ok(Self::Pt205),
206u64 => Ok(Self::Pt206),
207u64 => Ok(Self::Pt207),
208u64 => Ok(Self::Pt208),
_ => Err(crate::errors::Error::Isotope(crate::Element::Pt, value)),
}
}
}
impl TryFrom<u8> for PlatinumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u16> for PlatinumIsotope {
type Error = crate::errors::Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_from(u64::from(value))
}
}
impl TryFrom<u32> for PlatinumIsotope {
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 PlatinumIsotope {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Pt165 => write!(f, "Pt165"),
Self::Pt166 => write!(f, "Pt166"),
Self::Pt167 => write!(f, "Pt167"),
Self::Pt168 => write!(f, "Pt168"),
Self::Pt169 => write!(f, "Pt169"),
Self::Pt170 => write!(f, "Pt170"),
Self::Pt171 => write!(f, "Pt171"),
Self::Pt172 => write!(f, "Pt172"),
Self::Pt173 => write!(f, "Pt173"),
Self::Pt174 => write!(f, "Pt174"),
Self::Pt175 => write!(f, "Pt175"),
Self::Pt176 => write!(f, "Pt176"),
Self::Pt177 => write!(f, "Pt177"),
Self::Pt178 => write!(f, "Pt178"),
Self::Pt179 => write!(f, "Pt179"),
Self::Pt180 => write!(f, "Pt180"),
Self::Pt181 => write!(f, "Pt181"),
Self::Pt182 => write!(f, "Pt182"),
Self::Pt183 => write!(f, "Pt183"),
Self::Pt184 => write!(f, "Pt184"),
Self::Pt185 => write!(f, "Pt185"),
Self::Pt186 => write!(f, "Pt186"),
Self::Pt187 => write!(f, "Pt187"),
Self::Pt188 => write!(f, "Pt188"),
Self::Pt189 => write!(f, "Pt189"),
Self::Pt190 => write!(f, "Pt190"),
Self::Pt191 => write!(f, "Pt191"),
Self::Pt192 => write!(f, "Pt192"),
Self::Pt193 => write!(f, "Pt193"),
Self::Pt194 => write!(f, "Pt194"),
Self::Pt195 => write!(f, "Pt195"),
Self::Pt196 => write!(f, "Pt196"),
Self::Pt197 => write!(f, "Pt197"),
Self::Pt198 => write!(f, "Pt198"),
Self::Pt199 => write!(f, "Pt199"),
Self::Pt200 => write!(f, "Pt200"),
Self::Pt201 => write!(f, "Pt201"),
Self::Pt202 => write!(f, "Pt202"),
Self::Pt203 => write!(f, "Pt203"),
Self::Pt204 => write!(f, "Pt204"),
Self::Pt205 => write!(f, "Pt205"),
Self::Pt206 => write!(f, "Pt206"),
Self::Pt207 => write!(f, "Pt207"),
Self::Pt208 => write!(f, "Pt208"),
}
}
}
#[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 PlatinumIsotope::iter() {
let mass = isotope.relative_atomic_mass();
assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
}
}
#[test]
fn test_element() {
for isotope in PlatinumIsotope::iter() {
let element = isotope.element();
assert_eq!(element, crate::Element::Pt, "Element should be correct for {isotope:?}");
}
}
#[test]
fn test_mass_number() {
for isotope in PlatinumIsotope::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 PlatinumIsotope::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 = PlatinumIsotope::most_abundant_isotope();
let _ = most_abundant.relative_atomic_mass();
}
#[test]
fn test_from_isotope() {
for isotope in PlatinumIsotope::iter() {
let iso: crate::Isotope = isotope.into();
match iso {
crate::Isotope::Pt(i) => assert_eq!(i, isotope),
_ => panic!("Wrong isotope type"),
}
}
}
#[test]
fn test_from_element() {
for isotope in PlatinumIsotope::iter() {
let elem: crate::Element = isotope.into();
assert_eq!(elem, crate::Element::Pt);
}
}
#[test]
fn test_try_from_mass_number() {
for isotope in PlatinumIsotope::iter() {
let mass = isotope.mass_number();
let iso = PlatinumIsotope::try_from(mass).unwrap();
assert_eq!(iso, isotope);
let iso_u32 = PlatinumIsotope::try_from(u32::from(mass)).unwrap();
assert_eq!(iso_u32, isotope);
if let Ok(mass_u8) = u8::try_from(mass) {
let iso_u8 = PlatinumIsotope::try_from(mass_u8).unwrap();
assert_eq!(iso_u8, isotope);
}
}
assert!(PlatinumIsotope::try_from(0_u16).is_err());
assert!(PlatinumIsotope::try_from(1000_u16).is_err());
assert!(PlatinumIsotope::try_from(0_u32).is_err());
assert!(PlatinumIsotope::try_from(1000_u32).is_err());
assert!(PlatinumIsotope::try_from(0_u8).is_err());
}
#[test]
fn test_display() {
for isotope in PlatinumIsotope::iter() {
let s = alloc::format!("{isotope}");
assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
}
}
}