knope_versioning/semver/
rule.rs1use std::fmt::Display;
2
3use tracing::debug;
4
5use super::Label;
6use crate::changes::{Change, ChangeType};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
10pub enum Rule {
11 Stable(Stable),
12 Pre { label: Label, stable_rule: Stable },
13 Release,
14}
15
16impl From<Stable> for Rule {
17 fn from(conventional_rule: Stable) -> Self {
18 Self::Stable(conventional_rule)
19 }
20}
21
22#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
24pub enum Stable {
25 Major,
26 Minor,
27 #[default]
28 Patch,
29}
30
31impl<'a, T: IntoIterator<Item = &'a Change>> From<T> for Stable {
32 fn from(changes: T) -> Self {
33 changes
34 .into_iter()
35 .map(|change| {
36 let rule = Self::from(&change.change_type);
37 debug!(
38 "{change_source}\n\timplies rule {rule}",
39 change_source = change.original_source
40 );
41 rule
42 })
43 .max()
44 .unwrap_or_default()
45 }
46}
47
48impl Display for Stable {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 match self {
51 Stable::Major => write!(f, "MAJOR"),
52 Stable::Minor => write!(f, "MINOR"),
53 Stable::Patch => write!(f, "PATCH"),
54 }
55 }
56}
57
58impl Ord for Stable {
59 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
60 match (self, other) {
61 (Self::Major, Self::Major)
62 | (Self::Minor, Self::Minor)
63 | (Self::Patch, Self::Patch) => std::cmp::Ordering::Equal,
64 (Self::Major, _) | (_, Self::Patch) => std::cmp::Ordering::Greater,
65 (_, Self::Major) | (Self::Patch, _) => std::cmp::Ordering::Less,
66 }
67 }
68}
69
70impl PartialOrd for Stable {
71 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
72 Some(self.cmp(other))
73 }
74}
75
76impl From<&ChangeType> for Stable {
77 fn from(value: &ChangeType) -> Self {
78 match value {
79 ChangeType::Feature => Self::Minor,
80 ChangeType::Breaking => Self::Major,
81 ChangeType::Custom(_) | ChangeType::Fix => Self::Patch,
82 }
83 }
84}