Skip to main content

semver_common/models/
commit_bucket.rs

1use crate::Commit;
2use derive_getters::Getters;
3use serde::{Deserialize, Serialize};
4use std::fmt::Display;
5
6/// A container for a kind of change pattern that represents a commit that matches said pattern,
7/// as well as a vector of Commit objects that match the pattern for that kind of change.
8#[derive(Serialize, Deserialize, Debug, Getters, Clone)]
9pub struct CommitBucket {
10    priority: u32,
11    kind: String,
12    commits: Vec<Commit>,
13}
14
15impl Ord for CommitBucket {
16    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
17        if self.priority > other.priority {
18            return std::cmp::Ordering::Greater;
19        } else if self.priority < other.priority {
20            return std::cmp::Ordering::Less;
21        }
22        std::cmp::Ordering::Equal
23    }
24}
25
26impl Eq for CommitBucket {}
27
28impl PartialOrd for CommitBucket {
29    fn ge(&self, other: &Self) -> bool {
30        self.priority >= other.priority
31    }
32
33    fn gt(&self, other: &Self) -> bool {
34        self.priority > other.priority
35    }
36
37    fn le(&self, other: &Self) -> bool {
38        self.priority <= other.priority
39    }
40
41    fn lt(&self, other: &Self) -> bool {
42        self.priority < other.priority
43    }
44
45    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
46        Some(self.cmp(other))
47    }
48}
49
50impl PartialEq for CommitBucket {
51    fn eq(&self, other: &Self) -> bool {
52        if self.commits.len() != other.commits.len() || self.kind != other.kind {
53            return false;
54        }
55        for i in 0..self.commits.len() {
56            if self.commits[i] != other.commits[i] {
57                return false;
58            }
59        }
60        true
61    }
62}
63
64impl Display for CommitBucket {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        writeln!(f, "## {}\n", self.kind)?;
67        let mut commits = self.commits.clone();
68        commits.sort();
69        for commit in commits.iter() {
70            write!(f, "- {}", commit)?;
71        }
72        Ok(())
73    }
74}
75
76impl CommitBucket {
77    pub fn new(kind: &str, priority: u32) -> Self {
78        CommitBucket {
79            priority,
80            kind: String::from(kind),
81            commits: vec![],
82        }
83    }
84
85    pub fn add(&mut self, commit: Commit) {
86        self.commits.push(commit);
87    }
88}
89
90#[cfg(test)]
91mod test {
92    use crate::mock;
93
94    use super::*;
95
96    #[test]
97    fn test_commitbucket_add() {
98        let mut bucket = CommitBucket::new("Feature", 1);
99        let commit_one = mock::commit::create("feat: this is a test one");
100        let commit_two = mock::commit::create("feat: this is a test two");
101        bucket.add(commit_one);
102        bucket.add(commit_two);
103
104        assert_eq!(bucket.kind(), "Feature");
105        assert_eq!(bucket.commits()[0].message(), "feat: this is a test one");
106        assert_eq!(bucket.commits()[1].message(), "feat: this is a test two");
107    }
108
109    #[test]
110    fn test_commitbucket_fmt() {
111        let mut bucket = CommitBucket::new("Feature", 1);
112        let commit_one = mock::commit::create("feat: this is a test one");
113        let commit_two = mock::commit::create("feat: this is a test two");
114        bucket.add(commit_one);
115        bucket.add(commit_two);
116
117        let displayed = format!("{}", bucket);
118        assert_eq!(
119            &displayed,
120            "## Feature\n\n- feat: this is a test one\n- feat: this is a test two\n"
121        );
122    }
123}