semver_extra/
increment.rs

1use core::fmt::Display;
2use core::str::FromStr;
3
4use clap::ValueEnum;
5use semver::{BuildMetadata, Prerelease, Version};
6
7use crate::{error::ErrorKind, Error};
8
9#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, ValueEnum)]
10pub enum IncrementLevel {
11    #[default]
12    Patch,
13    Minor,
14    Major,
15}
16
17impl Display for IncrementLevel {
18    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19        write!(
20            f,
21            "{}",
22            match self {
23                IncrementLevel::Patch => "patch",
24                IncrementLevel::Minor => "minor",
25                IncrementLevel::Major => "major",
26            }
27        )
28    }
29}
30
31impl FromStr for IncrementLevel {
32    type Err = Error;
33
34    fn from_str(s: &str) -> Result<Self, Self::Err> {
35        match s.to_lowercase().as_str() {
36            "patch" => Ok(Self::Patch),
37            "minor" => Ok(Self::Minor),
38            "major" => Ok(Self::Major),
39            _ => Err(Error::new(ErrorKind::InvalidIncrementLevel(s.to_string()))),
40        }
41    }
42}
43
44pub trait Increment {
45    fn increment(&mut self, level: IncrementLevel) -> &mut Self;
46}
47
48impl Increment for Version {
49    fn increment(&mut self, level: IncrementLevel) -> &mut Self {
50        self.build = BuildMetadata::EMPTY;
51        self.pre = Prerelease::EMPTY;
52        self.patch += 1;
53        if level > IncrementLevel::Patch {
54            self.patch = 0;
55            self.minor += 1;
56        }
57        if level > IncrementLevel::Minor {
58            self.minor = 0;
59            self.major += 1;
60        }
61        self
62    }
63}