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