semver_common/models/
commit_map.rs1use 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 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}