winget_types/shared/
manifest_version.rs

1use std::{num::ParseIntError, str::FromStr};
2
3use const_format::{ConstDebug, Error, Formatter, writec};
4use derive_more::Display;
5use serde_with::{DeserializeFromStr, SerializeDisplay};
6use thiserror::Error;
7
8#[derive(
9    ConstDebug,
10    Debug,
11    Display,
12    Eq,
13    PartialEq,
14    Ord,
15    PartialOrd,
16    Hash,
17    SerializeDisplay,
18    DeserializeFromStr,
19)]
20#[display("{_0}.{_1}.{_2}")]
21pub struct ManifestVersion(u16, u16, u16);
22
23#[derive(Error, Debug, Eq, PartialEq)]
24pub enum ManifestVersionError {
25    #[error("Manifest version must have a major part")]
26    NoMajorVersion,
27    #[error("Manifest version must have a minor part")]
28    NoMinorVersion,
29    #[error("Manifest version must have a patch part")]
30    NoPatchVersion,
31    #[error(transparent)]
32    InvalidPart(#[from] ParseIntError),
33}
34
35impl ManifestVersion {
36    pub const DEFAULT: Self = Self(1, 9, 0);
37    const PARTS_COUNT: u8 = 3;
38    const SEPARATOR: char = '.';
39
40    pub fn new<S: AsRef<str>>(input: S) -> Result<Self, ManifestVersionError> {
41        let mut parts = input
42            .as_ref()
43            .splitn(Self::PARTS_COUNT as usize, Self::SEPARATOR);
44        let major = parts
45            .next()
46            .ok_or(ManifestVersionError::NoMajorVersion)?
47            .parse::<u16>()?;
48        let minor = parts
49            .next()
50            .ok_or(ManifestVersionError::NoMinorVersion)?
51            .parse::<u16>()?;
52        let patch = parts
53            .next()
54            .ok_or(ManifestVersionError::NoPatchVersion)?
55            .parse::<u16>()?;
56        Ok(Self(major, minor, patch))
57    }
58
59    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
60        writec!(f, "{}.{}.{}", self.0, self.1, self.2)
61    }
62}
63
64impl Default for ManifestVersion {
65    fn default() -> Self {
66        Self::DEFAULT
67    }
68}
69
70impl FromStr for ManifestVersion {
71    type Err = ManifestVersionError;
72
73    fn from_str(s: &str) -> Result<Self, Self::Err> {
74        Self::new(s)
75    }
76}