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 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, 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 let author = commit.author();
101 let author = author.name().or_else(|| author.email()).unwrap_or("");
102
103 let hash = format!("{}", commit.id());
105
106 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}