gitmoji_changelog/
commit.rs

1use git2::{Repository, Revwalk};
2use regex::Regex;
3use std::collections::HashMap;
4
5lazy_static! {
6    static ref RE_SUMMARY: Regex = Regex::new(r":(.*?):(.*)").unwrap();
7
8    static ref EMOJIES: HashMap<&'static str, &'static str> = {
9        let mut m = HashMap::new();
10        // You can use gen_code.js to generate this
11        m.insert("hammer", "πŸ”¨");
12        m.insert("art", "🎨");
13        m.insert("zap", "⚑️");
14        m.insert("fire", "πŸ”₯");
15        m.insert("bug", "πŸ›");
16        m.insert("ambulance", "πŸš‘");
17        m.insert("sparkles", "✨");
18        m.insert("memo", "πŸ“");
19        m.insert("rocket", "πŸš€");
20        m.insert("lipstick", "πŸ’„");
21        m.insert("tada", "πŸŽ‰");
22        m.insert("white_check_mark", "βœ…");
23        m.insert("lock", "πŸ”’");
24        m.insert("apple", "🍎");
25        m.insert("penguin", "🐧");
26        m.insert("checkered_flag", "🏁");
27        m.insert("robot", "πŸ€–");
28        m.insert("green_apple", "🍏");
29        m.insert("bookmark", "πŸ”–");
30        m.insert("rotating_light", "🚨");
31        m.insert("construction", "🚧");
32        m.insert("green_heart", "πŸ’š");
33        m.insert("arrow_down", "⬇️");
34        m.insert("arrow_up", "⬆️");
35        m.insert("pushpin", "πŸ“Œ");
36        m.insert("construction_worker", "πŸ‘·");
37        m.insert("chart_with_upwards_trend", "πŸ“ˆ");
38        m.insert("recycle", "♻️");
39        m.insert("whale", "🐳");
40        m.insert("heavy_plus_sign", "βž•");
41        m.insert("heavy_minus_sign", "βž–");
42        m.insert("wrench", "πŸ”§");
43        m.insert("globe_with_meridians", "🌐");
44        m.insert("pencil2", "✏️");
45        m.insert("hankey", "πŸ’©");
46        m.insert("rewind", "βͺ");
47        m.insert("twisted_rightwards_arrows", "πŸ”€");
48        m.insert("package", "πŸ“¦");
49        m.insert("alien", "πŸ‘½");
50        m.insert("truck", "🚚");
51        m.insert("page_facing_up", "πŸ“„");
52        m.insert("boom", "πŸ’₯");
53        m.insert("bento", "🍱");
54        m.insert("ok_hand", "πŸ‘Œ");
55        m.insert("wheelchair", "♿️");
56        m.insert("bulb", "πŸ’‘");
57        m.insert("beers", "🍻");
58        m.insert("speech_balloon", "πŸ’¬");
59        m.insert("card_file_box", "πŸ—ƒ");
60        m.insert("loud_sound", "πŸ”Š");
61        m.insert("mute", "πŸ”‡");
62        m.insert("busts_in_silhouette", "πŸ‘₯");
63        m.insert("children_crossing", "🚸");
64        m.insert("building_construction", "πŸ—");
65        m.insert("iphone", "πŸ“±");
66        m.insert("clown_face", "🀑");
67        m.insert("egg", "πŸ₯š");
68        m.insert("see_no_evil", "πŸ™ˆ");
69        m.insert("camera_flash", "πŸ“Έ");
70        m.insert("alembic", "βš—");
71        m.insert("mag", "πŸ”");
72        m.insert("wheel_of_dharma", "☸️");
73        m.insert("label", "🏷️");
74        m
75    };
76}
77
78#[derive(Debug, Eq, PartialEq, Serialize, Clone)]
79pub struct Commit {
80    pub hash: String,
81    pub summary: String, // TODO: try to convert this so str
82    pub author: String,
83    pub emoji_code: String,
84    pub emoji: String,
85}
86
87impl Commit {
88    pub fn new(hash: String, summary: &str, author: &str, emoji_code: &str) -> Commit {
89        Commit {
90            hash,
91            summary: summary.to_string(),
92            author: author.to_string(),
93            emoji_code: emoji_code.to_string(),
94            emoji: EMOJIES.get(emoji_code).unwrap_or(&emoji_code).to_string(),
95        }
96    }
97
98    pub fn from_git2(commit: &git2::Commit) -> Option<Commit> {
99        // author
100        let author = commit.author();
101        let author = author.name().or_else(|| author.email()).unwrap_or("");
102
103        // hash (full, since git2r doesn't support shorthash yet )
104        let hash = format!("{}", commit.id());
105
106        // summary and new commit
107        let summary = commit.summary().unwrap_or("");
108        match RE_SUMMARY.captures(summary) {
109            None => None,
110            Some(captures) => {
111                let emoji_code = captures.get(1).unwrap().as_str();
112                let summary = captures.get(2).unwrap().as_str().trim();
113
114                Some(Commit::new(hash, summary, author, emoji_code))
115            }
116        }
117    }
118
119    pub fn from_revwalk(repository: &Repository, revwalk: &mut Revwalk) -> Vec<Commit> {
120        revwalk
121            .filter_map(|oid| repository.find_commit(oid.unwrap()).ok())
122            .filter_map(|raw_commit| Commit::from_git2(&raw_commit))
123            .collect()
124    }
125}