elements_rs 0.2.6

A comprehensive library for chemical elements and their isotopes with rich metadata
Documentation
//! Isotopes of the element Potassium
#[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))]
/// Isotopes of the element Potassium
pub enum PotassiumIsotope {
    /// Isotope K31 of Potassium
    K31,
    /// Isotope K33 of Potassium
    K33,
    /// Isotope K34 of Potassium
    K34,
    /// Isotope K35 of Potassium
    K35,
    /// Isotope K36 of Potassium
    K36,
    /// Isotope K37 of Potassium
    K37,
    /// Isotope K38 of Potassium
    K38,
    /// Isotope K39 of Potassium
    K39,
    /// Isotope K40 of Potassium
    K40,
    /// Isotope K41 of Potassium
    K41,
    /// Isotope K42 of Potassium
    K42,
    /// Isotope K43 of Potassium
    K43,
    /// Isotope K44 of Potassium
    K44,
    /// Isotope K45 of Potassium
    K45,
    /// Isotope K46 of Potassium
    K46,
    /// Isotope K47 of Potassium
    K47,
    /// Isotope K48 of Potassium
    K48,
    /// Isotope K49 of Potassium
    K49,
    /// Isotope K50 of Potassium
    K50,
    /// Isotope K51 of Potassium
    K51,
    /// Isotope K52 of Potassium
    K52,
    /// Isotope K53 of Potassium
    K53,
    /// Isotope K54 of Potassium
    K54,
    /// Isotope K55 of Potassium
    K55,
    /// Isotope K56 of Potassium
    K56,
    /// Isotope K57 of Potassium
    K57,
    /// Isotope K59 of Potassium
    K59,
}
impl super::RelativeAtomicMass for PotassiumIsotope {
    #[inline]
    fn relative_atomic_mass(&self) -> f64 {
        match self {
            Self::K31 => 31.03678f64,
            Self::K33 => 33.00756f64,
            Self::K34 => 33.99869f64,
            Self::K35 => 34.98800541f64,
            Self::K36 => 35.98130201f64,
            Self::K37 => 36.97337589f64,
            Self::K38 => 37.96908112f64,
            Self::K39 => 38.9637064864f64,
            Self::K40 => 39.963998166f64,
            Self::K41 => 40.9618252579f64,
            Self::K42 => 41.96240231f64,
            Self::K43 => 42.9607347f64,
            Self::K44 => 43.96158699f64,
            Self::K45 => 44.96069149f64,
            Self::K46 => 45.96198159f64,
            Self::K47 => 46.9616616f64,
            Self::K48 => 47.96534119f64,
            Self::K49 => 48.96821075f64,
            Self::K50 => 49.97238f64,
            Self::K51 => 50.975828f64,
            Self::K52 => 51.98224f64,
            Self::K53 => 52.98746f64,
            Self::K54 => 53.99463f64,
            Self::K55 => 55.00076f64,
            Self::K56 => 56.00851f64,
            Self::K57 => 57.015169f64,
            Self::K59 => 59.030864f64,
        }
    }
}
impl super::ElementVariant for PotassiumIsotope {
    #[inline]
    fn element(&self) -> crate::Element {
        crate::Element::K
    }
}
impl super::MassNumber for PotassiumIsotope {
    #[inline]
    fn mass_number(&self) -> u16 {
        match self {
            Self::K31 => 31u16,
            Self::K33 => 33u16,
            Self::K34 => 34u16,
            Self::K35 => 35u16,
            Self::K36 => 36u16,
            Self::K37 => 37u16,
            Self::K38 => 38u16,
            Self::K39 => 39u16,
            Self::K40 => 40u16,
            Self::K41 => 41u16,
            Self::K42 => 42u16,
            Self::K43 => 43u16,
            Self::K44 => 44u16,
            Self::K45 => 45u16,
            Self::K46 => 46u16,
            Self::K47 => 47u16,
            Self::K48 => 48u16,
            Self::K49 => 49u16,
            Self::K50 => 50u16,
            Self::K51 => 51u16,
            Self::K52 => 52u16,
            Self::K53 => 53u16,
            Self::K54 => 54u16,
            Self::K55 => 55u16,
            Self::K56 => 56u16,
            Self::K57 => 57u16,
            Self::K59 => 59u16,
        }
    }
}
impl super::IsotopicComposition for PotassiumIsotope {
    #[inline]
    fn isotopic_composition(&self) -> Option<f64> {
        match self {
            Self::K39 => Some(0.932581f64),
            Self::K40 => Some(0.000117f64),
            Self::K41 => Some(0.067302f64),
            _ => None,
        }
    }
}
impl super::MostAbundantIsotope for PotassiumIsotope {
    fn most_abundant_isotope() -> Self {
        Self::K39
    }
}
impl From<PotassiumIsotope> for crate::Isotope {
    fn from(isotope: PotassiumIsotope) -> Self {
        crate::Isotope::K(isotope)
    }
}
impl From<PotassiumIsotope> for crate::Element {
    fn from(_isotope: PotassiumIsotope) -> Self {
        crate::Element::K
    }
}
impl TryFrom<u64> for PotassiumIsotope {
    type Error = crate::errors::Error;
    fn try_from(value: u64) -> Result<Self, Self::Error> {
        match value {
            31u64 => Ok(Self::K31),
            33u64 => Ok(Self::K33),
            34u64 => Ok(Self::K34),
            35u64 => Ok(Self::K35),
            36u64 => Ok(Self::K36),
            37u64 => Ok(Self::K37),
            38u64 => Ok(Self::K38),
            39u64 => Ok(Self::K39),
            40u64 => Ok(Self::K40),
            41u64 => Ok(Self::K41),
            42u64 => Ok(Self::K42),
            43u64 => Ok(Self::K43),
            44u64 => Ok(Self::K44),
            45u64 => Ok(Self::K45),
            46u64 => Ok(Self::K46),
            47u64 => Ok(Self::K47),
            48u64 => Ok(Self::K48),
            49u64 => Ok(Self::K49),
            50u64 => Ok(Self::K50),
            51u64 => Ok(Self::K51),
            52u64 => Ok(Self::K52),
            53u64 => Ok(Self::K53),
            54u64 => Ok(Self::K54),
            55u64 => Ok(Self::K55),
            56u64 => Ok(Self::K56),
            57u64 => Ok(Self::K57),
            59u64 => Ok(Self::K59),
            _ => Err(crate::errors::Error::Isotope(crate::Element::K, value)),
        }
    }
}
impl TryFrom<u8> for PotassiumIsotope {
    type Error = crate::errors::Error;
    fn try_from(value: u8) -> Result<Self, Self::Error> {
        Self::try_from(u64::from(value))
    }
}
impl TryFrom<u16> for PotassiumIsotope {
    type Error = crate::errors::Error;
    fn try_from(value: u16) -> Result<Self, Self::Error> {
        Self::try_from(u64::from(value))
    }
}
impl TryFrom<u32> for PotassiumIsotope {
    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 PotassiumIsotope {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::K31 => write!(f, "K31"),
            Self::K33 => write!(f, "K33"),
            Self::K34 => write!(f, "K34"),
            Self::K35 => write!(f, "K35"),
            Self::K36 => write!(f, "K36"),
            Self::K37 => write!(f, "K37"),
            Self::K38 => write!(f, "K38"),
            Self::K39 => write!(f, "K39"),
            Self::K40 => write!(f, "K40"),
            Self::K41 => write!(f, "K41"),
            Self::K42 => write!(f, "K42"),
            Self::K43 => write!(f, "K43"),
            Self::K44 => write!(f, "K44"),
            Self::K45 => write!(f, "K45"),
            Self::K46 => write!(f, "K46"),
            Self::K47 => write!(f, "K47"),
            Self::K48 => write!(f, "K48"),
            Self::K49 => write!(f, "K49"),
            Self::K50 => write!(f, "K50"),
            Self::K51 => write!(f, "K51"),
            Self::K52 => write!(f, "K52"),
            Self::K53 => write!(f, "K53"),
            Self::K54 => write!(f, "K54"),
            Self::K55 => write!(f, "K55"),
            Self::K56 => write!(f, "K56"),
            Self::K57 => write!(f, "K57"),
            Self::K59 => write!(f, "K59"),
        }
    }
}
#[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 PotassiumIsotope::iter() {
            let mass = isotope.relative_atomic_mass();
            assert!(mass > 0.0, "Mass should be positive for {isotope:?}");
        }
    }
    #[test]
    fn test_element() {
        for isotope in PotassiumIsotope::iter() {
            let element = isotope.element();
            assert_eq!(element, crate::Element::K, "Element should be correct for {isotope:?}");
        }
    }
    #[test]
    fn test_mass_number() {
        for isotope in PotassiumIsotope::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 PotassiumIsotope::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 = PotassiumIsotope::most_abundant_isotope();
        let _ = most_abundant.relative_atomic_mass();
    }
    #[test]
    fn test_from_isotope() {
        for isotope in PotassiumIsotope::iter() {
            let iso: crate::Isotope = isotope.into();
            match iso {
                crate::Isotope::K(i) => assert_eq!(i, isotope),
                _ => panic!("Wrong isotope type"),
            }
        }
    }
    #[test]
    fn test_from_element() {
        for isotope in PotassiumIsotope::iter() {
            let elem: crate::Element = isotope.into();
            assert_eq!(elem, crate::Element::K);
        }
    }
    #[test]
    fn test_try_from_mass_number() {
        for isotope in PotassiumIsotope::iter() {
            let mass = isotope.mass_number();
            let iso = PotassiumIsotope::try_from(mass).unwrap();
            assert_eq!(iso, isotope);
            let iso_u32 = PotassiumIsotope::try_from(u32::from(mass)).unwrap();
            assert_eq!(iso_u32, isotope);
            if let Ok(mass_u8) = u8::try_from(mass) {
                let iso_u8 = PotassiumIsotope::try_from(mass_u8).unwrap();
                assert_eq!(iso_u8, isotope);
            }
        }
        assert!(PotassiumIsotope::try_from(0_u16).is_err());
        assert!(PotassiumIsotope::try_from(1000_u16).is_err());
        assert!(PotassiumIsotope::try_from(0_u32).is_err());
        assert!(PotassiumIsotope::try_from(1000_u32).is_err());
        assert!(PotassiumIsotope::try_from(0_u8).is_err());
    }
    #[test]
    fn test_display() {
        for isotope in PotassiumIsotope::iter() {
            let s = alloc::format!("{isotope}");
            assert!(!s.is_empty(), "Display should not be empty for {isotope:?}");
        }
    }
}