Skip to main content

semver_common/models/
commit_map.rs

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