ak_core/geometry/
atomic_number.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2pub struct AtomicNumber(u8);
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum AtomicNumberError {
6 OutOfRange { z: u8, max: u8 },
7 ConversionFailed,
8}
9
10impl AtomicNumber {
11 pub const MAX: u8 = 110;
12
13 pub fn new<T>(z: T) -> Result<Self, AtomicNumberError>
14 where
15 T: TryInto<u8>,
16 {
17 let z_u8: u8 = z
18 .try_into()
19 .map_err(|_| AtomicNumberError::ConversionFailed)?;
20
21 if z_u8 > 0 && z_u8 <= Self::MAX {
22 Ok(Self(z_u8))
23 } else {
24 Err(AtomicNumberError::OutOfRange {
25 z: z_u8,
26 max: Self::MAX,
27 })
28 }
29 }
30
31 pub const fn get(self) -> u8 {
32 self.0
33 }
34}
35
36#[cfg(test)]
37mod tests {
38
39 use crate::geometry::{AtomicNumber, AtomicNumberError};
40
41 #[test]
42 fn test_new() {
43 let z = AtomicNumber::new(100).unwrap();
44 assert_eq!(z.get(), 100);
45 }
46
47 #[test]
48 fn test_out_of_range_error() {
49 let z = AtomicNumber::new(111);
50 assert_eq!(z, Err(AtomicNumberError::OutOfRange { z: 111, max: 110 }));
51 }
52
53 #[test]
54 fn test_conversion_error() {
55 let z = AtomicNumber::new(2000);
56 assert_eq!(z, Err(AtomicNumberError::ConversionFailed));
57 }
58}