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