abs_data/models/typed/
version.rs

1use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
2use std::boxed::Box;
3use std::fmt;
4
5use crate::error_code::ErrorCode;
6use crate::result::Result;
7
8#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
9pub struct Version {
10    major: u8,
11    minor: u8,
12    patch: u8,
13    str: Box<str>,
14}
15
16impl Version {
17    pub fn new(major: u8, minor: u8, patch: u8) -> Self {
18        Version {
19            major,
20            minor,
21            patch,
22            str: format!("{}.{}.{}", major, minor, patch).into(),
23        }
24    }
25
26    pub fn one() -> Self {
27        Version::new(1, 0, 0)
28    }
29}
30
31impl Default for Version {
32    fn default() -> Self {
33        Self {
34            major: 1,
35            minor: 0,
36            patch: 0,
37            str: Self::one().to_string().into(),
38        }
39    }
40}
41
42impl AsRef<str> for Version {
43    fn as_ref(&self) -> &str {
44        &self.str
45    }
46}
47
48impl TryFrom<Box<str>> for Version {
49    type Error = ErrorCode;
50
51    fn try_from(s: Box<str>) -> Result<Self> {
52        let parts: Vec<&str> = s.split('.').collect();
53        if parts.len() != 3 {
54            return Err(ErrorCode::VersionStringNotCorrectLength(parts.len()));
55        }
56        let major = parts[0]
57            .parse()
58            .map_err(ErrorCode::VersionStringContainsUnknownChar)?;
59
60        let minor = parts[1]
61            .parse()
62            .map_err(ErrorCode::VersionStringContainsUnknownChar)?;
63
64        let patch = parts[2]
65            .parse()
66            .map_err(ErrorCode::VersionStringContainsUnknownChar)?;
67
68        Ok(Version::new(major, minor, patch))
69    }
70}
71
72impl fmt::Display for Version {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        write!(f, "{}", self.str)
75    }
76}
77
78impl Serialize for Version {
79    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
80    where
81        S: Serializer,
82    {
83        serializer.serialize_str(self.as_ref())
84    }
85}
86
87impl<'de> Deserialize<'de> for Version {
88    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
89    where
90        D: Deserializer<'de>,
91    {
92        let s: Box<str> = Deserialize::deserialize(deserializer)?;
93        s.try_into().map_err(de::Error::custom)
94    }
95}