aldrin_core/
protocol_version.rs1use crate::error::{ProtocolVersionError, ProtocolVersionErrorKind};
2use std::fmt;
3use std::str::FromStr;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
6pub struct ProtocolVersion {
7 minor: Minor,
8}
9
10impl ProtocolVersion {
11 pub const MAJOR: u32 = 1;
12 pub const V1_14: Self = Self { minor: Minor::V14 };
13 pub const V1_15: Self = Self { minor: Minor::V15 };
14 pub const V1_16: Self = Self { minor: Minor::V16 };
15 pub const V1_17: Self = Self { minor: Minor::V17 };
16 pub const V1_18: Self = Self { minor: Minor::V18 };
17 pub const V1_19: Self = Self { minor: Minor::V19 };
18 pub const MIN: Self = Self::V1_14;
19 pub const MAX: Self = Self::V1_19;
20
21 pub const fn new(major: u32, minor: u32) -> Result<Self, ProtocolVersionError> {
22 if major != Self::MAJOR {
23 return Err(ProtocolVersionError {
24 kind: ProtocolVersionErrorKind::InvalidMajor,
25 });
26 }
27
28 match minor {
29 14 => Ok(Self { minor: Minor::V14 }),
30 15 => Ok(Self { minor: Minor::V15 }),
31 16 => Ok(Self { minor: Minor::V16 }),
32 17 => Ok(Self { minor: Minor::V17 }),
33 18 => Ok(Self { minor: Minor::V18 }),
34 19 => Ok(Self { minor: Minor::V19 }),
35
36 _ => Err(ProtocolVersionError {
37 kind: ProtocolVersionErrorKind::InvalidMinor,
38 }),
39 }
40 }
41
42 pub const fn major(&self) -> u32 {
43 Self::MAJOR
44 }
45
46 pub const fn minor(&self) -> u32 {
47 self.minor as u32
48 }
49}
50
51#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
52enum Minor {
53 V14 = 14,
54 V15 = 15,
55 V16 = 16,
56 V17 = 17,
57 V18 = 18,
58 V19 = 19,
59}
60
61impl fmt::Display for ProtocolVersion {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 write!(f, "{}.{}", self.major(), self.minor())
64 }
65}
66
67impl FromStr for ProtocolVersion {
68 type Err = ProtocolVersionError;
69
70 fn from_str(s: &str) -> Result<Self, Self::Err> {
71 let (major, minor) = s.split_once('.').ok_or(ProtocolVersionErrorKind::Parse)?;
72 let major = major.parse().map_err(|_| ProtocolVersionErrorKind::Parse)?;
73 let minor = minor.parse().map_err(|_| ProtocolVersionErrorKind::Parse)?;
74 Self::new(major, minor)
75 }
76}
77
78#[cfg(test)]
79mod test {
80 use super::ProtocolVersion;
81 use crate::error::ProtocolVersionErrorKind;
82
83 #[test]
84 fn parse_protocol_version() {
85 assert_eq!("1.14".parse(), Ok(ProtocolVersion::V1_14));
86 assert_eq!("1.15".parse(), Ok(ProtocolVersion::V1_15));
87 assert_eq!("1.16".parse(), Ok(ProtocolVersion::V1_16));
88 assert_eq!("1.17".parse(), Ok(ProtocolVersion::V1_17));
89 assert_eq!("1.18".parse(), Ok(ProtocolVersion::V1_18));
90 assert_eq!("1.19".parse(), Ok(ProtocolVersion::V1_19));
91
92 assert_eq!(
93 "1.13".parse::<ProtocolVersion>(),
94 Err(ProtocolVersionErrorKind::InvalidMinor.into())
95 );
96 assert_eq!(
97 "1.20".parse::<ProtocolVersion>(),
98 Err(ProtocolVersionErrorKind::InvalidMinor.into())
99 );
100
101 assert_eq!(
102 "0.14".parse::<ProtocolVersion>(),
103 Err(ProtocolVersionErrorKind::InvalidMajor.into())
104 );
105 assert_eq!(
106 "1.0".parse::<ProtocolVersion>(),
107 Err(ProtocolVersionErrorKind::InvalidMinor.into())
108 );
109 assert_eq!(
110 "1.4294967295".parse::<ProtocolVersion>(),
111 Err(ProtocolVersionErrorKind::InvalidMinor.into())
112 );
113
114 assert_eq!(
115 "1.".parse::<ProtocolVersion>(),
116 Err(ProtocolVersionErrorKind::Parse.into())
117 );
118 assert_eq!(
119 ".14".parse::<ProtocolVersion>(),
120 Err(ProtocolVersionErrorKind::Parse.into())
121 );
122 assert_eq!(
123 "".parse::<ProtocolVersion>(),
124 Err(ProtocolVersionErrorKind::Parse.into())
125 );
126 }
127}