winget_types/shared/
manifest_version.rs1use core::{fmt, num::ParseIntError, str::FromStr};
2
3use thiserror::Error;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
7#[cfg_attr(feature = "serde", serde(try_from = "&str"))]
8pub struct ManifestVersion(u16, u16, u16);
9
10#[derive(Error, Debug, Eq, PartialEq)]
11pub enum ManifestVersionError {
12 #[error("Manifest version must have a major part")]
13 NoMajorVersion,
14 #[error("Manifest version must have a minor part")]
15 NoMinorVersion,
16 #[error("Manifest version must have a patch part")]
17 NoPatchVersion,
18 #[error(transparent)]
19 InvalidPart(#[from] ParseIntError),
20}
21
22impl ManifestVersion {
23 pub const DEFAULT: Self = Self(1, 10, 0);
24 const PARTS_COUNT: u8 = 3;
25 const SEPARATOR: char = '.';
26
27 #[must_use]
29 #[inline]
30 pub const fn new(major: u16, minor: u16, patch: u16) -> Self {
31 Self(major, minor, patch)
32 }
33}
34
35impl Default for ManifestVersion {
36 fn default() -> Self {
37 Self::DEFAULT
38 }
39}
40
41impl fmt::Display for ManifestVersion {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(f, "{}.{}.{}", self.0, self.1, self.2)
44 }
45}
46
47impl FromStr for ManifestVersion {
48 type Err = ManifestVersionError;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 let mut parts = s.splitn(Self::PARTS_COUNT as usize, Self::SEPARATOR);
52
53 let major = parts
54 .next()
55 .ok_or(ManifestVersionError::NoMajorVersion)?
56 .parse::<u16>()?;
57 let minor = parts
58 .next()
59 .ok_or(ManifestVersionError::NoMinorVersion)?
60 .parse::<u16>()?;
61 let patch = parts
62 .next()
63 .ok_or(ManifestVersionError::NoPatchVersion)?
64 .parse::<u16>()?;
65
66 Ok(Self(major, minor, patch))
67 }
68}
69
70impl TryFrom<&str> for ManifestVersion {
71 type Error = ManifestVersionError;
72
73 #[inline]
74 fn try_from(value: &str) -> Result<Self, Self::Error> {
75 value.parse()
76 }
77}
78
79#[cfg(feature = "serde")]
80impl serde::Serialize for ManifestVersion
81where
82 Self: fmt::Display,
83{
84 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
85 where
86 S: serde::Serializer,
87 {
88 serializer.collect_str(&self)
89 }
90}