Skip to main content

winget_types/
manifest_version.rs

1use core::{fmt, num::ParseIntError, str::FromStr};
2
3use compact_str::CompactString;
4use thiserror::Error;
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
8#[cfg_attr(feature = "serde", serde(try_from = "CompactString"))]
9pub struct ManifestVersion(u16, u16, u16);
10
11#[derive(Error, Debug, Eq, PartialEq)]
12pub enum ManifestVersionError {
13    #[error("Manifest version must have a major part")]
14    NoMajorVersion,
15    #[error("Manifest version must have a minor part")]
16    NoMinorVersion,
17    #[error("Manifest version must have a patch part")]
18    NoPatchVersion,
19    #[error(transparent)]
20    InvalidPart(#[from] ParseIntError),
21}
22
23impl ManifestVersion {
24    pub const DEFAULT: Self = Self(1, 12, 0);
25    const PARTS_COUNT: u8 = 3;
26    const SEPARATOR: char = '.';
27
28    /// Creates a new `ManifestVersion` from a `major`, `minor`, and `patch` part.
29    #[must_use]
30    #[inline]
31    pub const fn new(major: u16, minor: u16, patch: u16) -> Self {
32        Self(major, minor, patch)
33    }
34
35    /// Returns the major version.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// # use winget_types::ManifestVersion;
41    /// let minimum_os_version = ManifestVersion::new(1, 9, 0);
42    /// assert_eq!(minimum_os_version.major(), 1);
43    /// ```
44    #[must_use]
45    #[inline]
46    pub const fn major(&self) -> u16 {
47        self.0
48    }
49
50    /// Returns the minor version.
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// # use winget_types::ManifestVersion;
56    /// let minimum_os_version = ManifestVersion::new(1, 9, 0);
57    /// assert_eq!(minimum_os_version.minor(), 9);
58    /// ```
59    #[must_use]
60    #[inline]
61    pub const fn minor(&self) -> u16 {
62        self.1
63    }
64
65    /// Returns the patch version.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// # use winget_types::ManifestVersion;
71    /// let minimum_os_version = ManifestVersion::new(1, 9, 0);
72    /// assert_eq!(minimum_os_version.patch(), 0);
73    /// ```
74    #[must_use]
75    #[inline]
76    pub const fn patch(&self) -> u16 {
77        self.2
78    }
79
80    /// Updates the manifest version to the [latest](Self::DEFAULT) version.
81    #[inline]
82    pub const fn update(&mut self) {
83        *self = Self::DEFAULT;
84    }
85}
86
87impl Default for ManifestVersion {
88    fn default() -> Self {
89        Self::DEFAULT
90    }
91}
92
93impl fmt::Display for ManifestVersion {
94    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        write!(f, "{}.{}.{}", self.0, self.1, self.2)
96    }
97}
98
99impl FromStr for ManifestVersion {
100    type Err = ManifestVersionError;
101
102    fn from_str(s: &str) -> Result<Self, Self::Err> {
103        let mut parts = s.splitn(Self::PARTS_COUNT as usize, Self::SEPARATOR);
104
105        let major = parts
106            .next()
107            .ok_or(ManifestVersionError::NoMajorVersion)?
108            .parse::<u16>()?;
109        let minor = parts
110            .next()
111            .ok_or(ManifestVersionError::NoMinorVersion)?
112            .parse::<u16>()?;
113        let patch = parts
114            .next()
115            .ok_or(ManifestVersionError::NoPatchVersion)?
116            .parse::<u16>()?;
117
118        Ok(Self::new(major, minor, patch))
119    }
120}
121
122impl From<(u16, u16, u16)> for ManifestVersion {
123    fn from((major, minor, patch): (u16, u16, u16)) -> Self {
124        Self::new(major, minor, patch)
125    }
126}
127
128impl TryFrom<CompactString> for ManifestVersion {
129    type Error = ManifestVersionError;
130
131    #[inline]
132    fn try_from(value: CompactString) -> Result<Self, Self::Error> {
133        value.parse()
134    }
135}
136
137#[cfg(feature = "serde")]
138impl serde::Serialize for ManifestVersion
139where
140    Self: fmt::Display,
141{
142    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
143    where
144        S: serde::Serializer,
145    {
146        serializer.collect_str(&self)
147    }
148}