Skip to main content

semver_common/models/
commit_map.rs

1use std::{collections::HashMap, fmt::Display};
2
3use crate::{Alert, Change, Commit, CommitBucket};
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize)]
7pub struct CommitMap {
8    map: HashMap<String, CommitBucket>,
9}
10
11impl Display for CommitMap {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        let mut buckets: Vec<&CommitBucket> = self.map.values().collect();
14        buckets.sort();
15        for bucket in buckets {
16            writeln!(f, "{}", bucket)?;
17        }
18        Ok(())
19    }
20}
21
22impl Default for CommitMap {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28impl CommitMap {
29    pub fn new() -> Self {
30        CommitMap {
31            map: HashMap::new(),
32        }
33    }
34
35    pub fn bucket(&self, key: &str) -> Option<&CommitBucket> {
36        self.map.get(key)
37    }
38
39    /// Inserts a commit into a bucket with the matching key.
40    /// Creates a bucket with that key if none exists already.
41    pub fn insert(&mut self, change: &Change, value: Commit) -> Result<(), Alert> {
42        if !self.map.contains_key(change.kind()) {
43            self.map.insert(
44                String::from(change.kind()),
45                CommitBucket::new(change.kind(), *change.priority()),
46            );
47        }
48        let bucket: &mut CommitBucket = self
49            .map
50            .get_mut(change.kind())
51            .ok_or("Could not find bucket in commit map.")?;
52        bucket.add(value);
53        Ok(())
54    }
55}
56
57#[cfg(test)]
58mod test {
59    use crate::mock;
60
61    use super::*;
62
63    #[test]
64    fn test_commitmap_insert_get() {
65        let mut commit_map = CommitMap::new();
66        let change_feat = mock::change::create("^feat(.|\n)*$", "Feature", 2);
67        let change_fix = mock::change::create("^fix(.|\n)*$", "Fix", 3);
68        let commit_one = mock::commit::create("feat(scope): a test header");
69        let commit_two = mock::commit::create("feat(scope): a test header two");
70        let commit_three = mock::commit::create("fix(scope): a test header two");
71        let result_one = commit_map.insert(&change_feat, commit_one.clone());
72        let result_two = commit_map.insert(&change_feat, commit_two.clone());
73        let result_three = commit_map.insert(&change_fix, commit_three.clone());
74        assert_eq!(result_one.is_ok(), true);
75        assert_eq!(result_two.is_ok(), true);
76        assert_eq!(result_three.is_ok(), true);
77
78        let actual_bucket_feat = commit_map.bucket("Feature").unwrap();
79        let actual_bucket_fix = commit_map.bucket("Fix").unwrap();
80
81        let mut expected_bucket_feat =
82            CommitBucket::new(change_feat.kind(), *change_feat.priority());
83        expected_bucket_feat.add(commit_one);
84        expected_bucket_feat.add(commit_two);
85
86        let mut expected_bucket_fix = CommitBucket::new(change_fix.kind(), *change_fix.priority());
87        expected_bucket_fix.add(commit_three);
88
89        assert_eq!(actual_bucket_feat, &expected_bucket_feat);
90        assert_eq!(actual_bucket_fix, &expected_bucket_fix);
91    }
92
93    #[test]
94    fn test_commitmap_fmt() {
95        let mut commit_map = CommitMap::new();
96        let change_feat = mock::change::create("^feat(.|\n)*$", "Feature", 2);
97        let change_fix = mock::change::create("^fix(.|\n)*$", "Fix", 3);
98        let commit_one = mock::commit::create("feat(scope): a test header");
99        let commit_two = mock::commit::create("feat(scope): a test header two");
100        let commit_three = mock::commit::create("fix(scope): a test header three");
101        commit_map.insert(&change_feat, commit_one.clone()).unwrap();
102        commit_map.insert(&change_feat, commit_two.clone()).unwrap();
103        commit_map
104            .insert(&change_fix, commit_three.clone())
105            .unwrap();
106
107        let commit_map_str = format!("{}", commit_map);
108        assert_eq!(
109            commit_map_str,
110            "## Feature\n\n- feat(scope): a test header\n- feat(scope): a test header two\n\n## Fix\n\n- fix(scope): a test header three\n\n"
111        );
112    }
113}