auto_gitmoji/matcher/
simple.rs1use super::{GitmojiMatcher, MatcherResult};
2use crate::emoji::EmojiLookup;
3use anyhow::Result;
4use serde_json;
5use std::collections::HashMap;
6
7pub struct SimpleMatcher {
9 keyword_map: HashMap<String, String>,
10}
11
12impl Default for SimpleMatcher {
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl SimpleMatcher {
19 pub fn new() -> Self {
20 let keyword_map = Self::load_keyword_map().unwrap_or_else(|_| Self::default_keyword_map());
21
22 Self { keyword_map }
23 }
24
25 fn load_keyword_map() -> Result<HashMap<String, String>> {
27 let json_content = include_str!("../../fixtures/keyword_map.json");
28 let map: HashMap<String, String> = serde_json::from_str(json_content)?;
29 Ok(map)
30 }
31
32 fn default_keyword_map() -> HashMap<String, String> {
34 let mut map = HashMap::new();
35
36 map.insert("add".to_string(), ":sparkles:".to_string());
38 map.insert("fix".to_string(), ":bug:".to_string());
39 map.insert("docs".to_string(), ":memo:".to_string());
40 map.insert("test".to_string(), ":white_check_mark:".to_string());
41 map.insert("refactor".to_string(), ":recycle:".to_string());
42 map.insert("remove".to_string(), ":fire:".to_string());
43 map.insert("perf".to_string(), ":zap:".to_string());
44 map.insert("style".to_string(), ":lipstick:".to_string());
45 map.insert("init".to_string(), ":tada:".to_string());
46 map.insert("security".to_string(), ":lock:".to_string());
47
48 map
49 }
50
51 fn find_first_keyword_match(&self, message: &str) -> Option<&str> {
57 let words: Vec<String> = message
59 .split_whitespace()
60 .map(|word| {
61 word.chars()
62 .filter(|c| c.is_alphanumeric() || *c == '-' || *c == '_')
63 .collect::<String>()
64 .to_lowercase()
65 })
66 .filter(|word| !word.is_empty())
67 .collect();
68
69 for word in words {
71 if let Some(emoji_code) = self.keyword_map.get(&word) {
72 return Some(emoji_code);
73 }
74 }
75
76 None
77 }
78}
79
80impl GitmojiMatcher for SimpleMatcher {
81 fn match_emoji(&self, message: &str) -> Result<MatcherResult> {
82 if let Some(emoji_code) = self.find_first_keyword_match(message) {
83 if let Some(emoji_unicode) = EmojiLookup::code_to_unicode(emoji_code) {
84 return Ok(Some((
86 emoji_code.to_string(),
87 emoji_unicode.to_string(),
88 1.0,
89 )));
90 }
91 }
92
93 Ok(Some((":sparkles:".to_string(), "✨".to_string(), 0.3)))
95 }
96
97 fn name(&self) -> &'static str {
98 "simple"
99 }
100}