use std::fmt;
use crate::{ChargeSign, IonValidationError};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ChargeMagnitude(u8);
impl ChargeMagnitude {
pub const fn new(magnitude: u8) -> Result<Self, IonValidationError> {
if magnitude == 0 {
Err(IonValidationError::ZeroChargeMagnitude)
} else {
Ok(Self(magnitude))
}
}
#[must_use]
pub const fn get(self) -> u8 {
self.0
}
}
impl fmt::Display for ChargeMagnitude {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IonCharge {
sign: ChargeSign,
magnitude: ChargeMagnitude,
}
impl IonCharge {
pub const fn positive(magnitude: u8) -> Result<Self, IonValidationError> {
Ok(Self {
sign: ChargeSign::Positive,
magnitude: match ChargeMagnitude::new(magnitude) {
Ok(value) => value,
Err(error) => return Err(error),
},
})
}
pub const fn negative(magnitude: u8) -> Result<Self, IonValidationError> {
Ok(Self {
sign: ChargeSign::Negative,
magnitude: match ChargeMagnitude::new(magnitude) {
Ok(value) => value,
Err(error) => return Err(error),
},
})
}
#[must_use]
pub const fn sign(self) -> ChargeSign {
self.sign
}
#[must_use]
pub const fn magnitude(self) -> u8 {
self.magnitude.get()
}
#[must_use]
pub const fn magnitude_value(self) -> ChargeMagnitude {
self.magnitude
}
#[must_use]
pub const fn is_positive(self) -> bool {
self.sign.is_positive()
}
#[must_use]
pub const fn is_negative(self) -> bool {
self.sign.is_negative()
}
#[must_use]
pub const fn is_cation(self) -> bool {
self.is_positive()
}
#[must_use]
pub const fn is_anion(self) -> bool {
self.is_negative()
}
}
impl fmt::Display for IonCharge {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.magnitude.get() == 1 {
write!(formatter, "{}", self.sign)
} else {
write!(formatter, "{}{}", self.magnitude, self.sign)
}
}
}