1use std::fmt;
2
3use crate::{ChargeSign, IonValidationError};
4
5#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct ChargeMagnitude(u8);
8
9impl ChargeMagnitude {
10 pub const fn new(magnitude: u8) -> Result<Self, IonValidationError> {
16 if magnitude == 0 {
17 Err(IonValidationError::ZeroChargeMagnitude)
18 } else {
19 Ok(Self(magnitude))
20 }
21 }
22
23 #[must_use]
25 pub const fn get(self) -> u8 {
26 self.0
27 }
28}
29
30impl fmt::Display for ChargeMagnitude {
31 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(formatter, "{}", self.0)
33 }
34}
35
36#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
38pub struct IonCharge {
39 sign: ChargeSign,
40 magnitude: ChargeMagnitude,
41}
42
43impl IonCharge {
44 pub const fn positive(magnitude: u8) -> Result<Self, IonValidationError> {
50 Ok(Self {
51 sign: ChargeSign::Positive,
52 magnitude: match ChargeMagnitude::new(magnitude) {
53 Ok(value) => value,
54 Err(error) => return Err(error),
55 },
56 })
57 }
58
59 pub const fn negative(magnitude: u8) -> Result<Self, IonValidationError> {
65 Ok(Self {
66 sign: ChargeSign::Negative,
67 magnitude: match ChargeMagnitude::new(magnitude) {
68 Ok(value) => value,
69 Err(error) => return Err(error),
70 },
71 })
72 }
73
74 #[must_use]
76 pub const fn sign(self) -> ChargeSign {
77 self.sign
78 }
79
80 #[must_use]
82 pub const fn magnitude(self) -> u8 {
83 self.magnitude.get()
84 }
85
86 #[must_use]
88 pub const fn magnitude_value(self) -> ChargeMagnitude {
89 self.magnitude
90 }
91
92 #[must_use]
94 pub const fn is_positive(self) -> bool {
95 self.sign.is_positive()
96 }
97
98 #[must_use]
100 pub const fn is_negative(self) -> bool {
101 self.sign.is_negative()
102 }
103
104 #[must_use]
106 pub const fn is_cation(self) -> bool {
107 self.is_positive()
108 }
109
110 #[must_use]
112 pub const fn is_anion(self) -> bool {
113 self.is_negative()
114 }
115}
116
117impl fmt::Display for IonCharge {
118 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
119 if self.magnitude.get() == 1 {
120 write!(formatter, "{}", self.sign)
121 } else {
122 write!(formatter, "{}{}", self.magnitude, self.sign)
123 }
124 }
125}