aldrin_core/
protocol_version.rs

1use std::fmt;
2use std::str::FromStr;
3use thiserror::Error;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
6#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
7pub struct ProtocolVersion {
8    major: u32,
9    minor: u32,
10}
11
12impl ProtocolVersion {
13    pub const V1_14: Self = Self::new(1, 14);
14    pub const V1_15: Self = Self::new(1, 15);
15    pub const V1_16: Self = Self::new(1, 16);
16    pub const V1_17: Self = Self::new(1, 17);
17    pub const V1_18: Self = Self::new(1, 18);
18    pub const V1_19: Self = Self::new(1, 19);
19    pub const V1_20: Self = Self::new(1, 20);
20
21    pub const fn new(major: u32, minor: u32) -> Self {
22        Self { major, minor }
23    }
24
25    pub const fn major(self) -> u32 {
26        self.major
27    }
28
29    pub const fn minor(self) -> u32 {
30        self.minor
31    }
32}
33
34impl fmt::Display for ProtocolVersion {
35    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36        write!(f, "{}.{}", self.major(), self.minor())
37    }
38}
39
40impl FromStr for ProtocolVersion {
41    type Err = ProtocolVersionParseError;
42
43    fn from_str(s: &str) -> Result<Self, Self::Err> {
44        let (major, minor) = s.split_once('.').ok_or(ProtocolVersionParseError)?;
45
46        let major = major.parse().map_err(|_| ProtocolVersionParseError)?;
47        let minor = minor.parse().map_err(|_| ProtocolVersionParseError)?;
48
49        Ok(Self::new(major, minor))
50    }
51}
52
53#[derive(Error, Debug, Copy, Clone, PartialEq, Eq)]
54#[error("failed to parse protocol version")]
55pub struct ProtocolVersionParseError;
56
57#[cfg(test)]
58mod test {
59    use super::{ProtocolVersion, ProtocolVersionParseError};
60
61    #[test]
62    fn parse_protocol_version() {
63        assert_eq!("1.14".parse(), Ok(ProtocolVersion::V1_14));
64        assert_eq!("1.15".parse(), Ok(ProtocolVersion::V1_15));
65        assert_eq!("1.16".parse(), Ok(ProtocolVersion::V1_16));
66        assert_eq!("1.17".parse(), Ok(ProtocolVersion::V1_17));
67        assert_eq!("1.18".parse(), Ok(ProtocolVersion::V1_18));
68        assert_eq!("1.19".parse(), Ok(ProtocolVersion::V1_19));
69        assert_eq!("1.20".parse(), Ok(ProtocolVersion::V1_20));
70
71        assert_eq!(
72            "1.4294967296".parse::<ProtocolVersion>(),
73            Err(ProtocolVersionParseError)
74        );
75
76        assert_eq!(
77            "1.".parse::<ProtocolVersion>(),
78            Err(ProtocolVersionParseError)
79        );
80
81        assert_eq!(
82            ".14".parse::<ProtocolVersion>(),
83            Err(ProtocolVersionParseError)
84        );
85
86        assert_eq!(
87            "".parse::<ProtocolVersion>(),
88            Err(ProtocolVersionParseError)
89        );
90    }
91}