gitmoji-changelog 0.4.0

Do you use gitmoji? Then generate your changelog with this app!
Documentation
use git2::{Repository, Revwalk};
use regex::Regex;
use std::collections::HashMap;

lazy_static! {
    static ref RE_SUMMARY: Regex = Regex::new(r":(.*?):(.*)").unwrap();

    static ref EMOJIES: HashMap<&'static str, &'static str> = {
        let mut m = HashMap::new();
        // You can use gen_code.js to generate this
        m.insert("hammer", "πŸ”¨");
        m.insert("art", "🎨");
        m.insert("zap", "⚑️");
        m.insert("fire", "πŸ”₯");
        m.insert("bug", "πŸ›");
        m.insert("ambulance", "πŸš‘");
        m.insert("sparkles", "✨");
        m.insert("memo", "πŸ“");
        m.insert("rocket", "πŸš€");
        m.insert("lipstick", "πŸ’„");
        m.insert("tada", "πŸŽ‰");
        m.insert("white_check_mark", "βœ…");
        m.insert("lock", "πŸ”’");
        m.insert("apple", "🍎");
        m.insert("penguin", "🐧");
        m.insert("checkered_flag", "🏁");
        m.insert("robot", "πŸ€–");
        m.insert("green_apple", "🍏");
        m.insert("bookmark", "πŸ”–");
        m.insert("rotating_light", "🚨");
        m.insert("construction", "🚧");
        m.insert("green_heart", "πŸ’š");
        m.insert("arrow_down", "⬇️");
        m.insert("arrow_up", "⬆️");
        m.insert("pushpin", "πŸ“Œ");
        m.insert("construction_worker", "πŸ‘·");
        m.insert("chart_with_upwards_trend", "πŸ“ˆ");
        m.insert("recycle", "♻️");
        m.insert("whale", "🐳");
        m.insert("heavy_plus_sign", "βž•");
        m.insert("heavy_minus_sign", "βž–");
        m.insert("wrench", "πŸ”§");
        m.insert("globe_with_meridians", "🌐");
        m.insert("pencil2", "✏️");
        m.insert("hankey", "πŸ’©");
        m.insert("rewind", "βͺ");
        m.insert("twisted_rightwards_arrows", "πŸ”€");
        m.insert("package", "πŸ“¦");
        m.insert("alien", "πŸ‘½");
        m.insert("truck", "🚚");
        m.insert("page_facing_up", "πŸ“„");
        m.insert("boom", "πŸ’₯");
        m.insert("bento", "🍱");
        m.insert("ok_hand", "πŸ‘Œ");
        m.insert("wheelchair", "♿️");
        m.insert("bulb", "πŸ’‘");
        m.insert("beers", "🍻");
        m.insert("speech_balloon", "πŸ’¬");
        m.insert("card_file_box", "πŸ—ƒ");
        m.insert("loud_sound", "πŸ”Š");
        m.insert("mute", "πŸ”‡");
        m.insert("busts_in_silhouette", "πŸ‘₯");
        m.insert("children_crossing", "🚸");
        m.insert("building_construction", "πŸ—");
        m.insert("iphone", "πŸ“±");
        m.insert("clown_face", "🀑");
        m.insert("egg", "πŸ₯š");
        m.insert("see_no_evil", "πŸ™ˆ");
        m.insert("camera_flash", "πŸ“Έ");
        m.insert("alembic", "βš—");
        m.insert("mag", "πŸ”");
        m.insert("wheel_of_dharma", "☸️");
        m.insert("label", "🏷️");
        m
    };
}

#[derive(Debug, Eq, PartialEq, Serialize, Clone)]
pub struct Commit {
    pub hash: String,
    pub summary: String, // TODO: try to convert this so str
    pub author: String,
    pub emoji_code: String,
    pub emoji: String,
}

impl Commit {
    pub fn new(hash: String, summary: &str, author: &str, emoji_code: &str) -> Commit {
        Commit {
            hash,
            summary: summary.to_string(),
            author: author.to_string(),
            emoji_code: emoji_code.to_string(),
            emoji: EMOJIES.get(emoji_code).unwrap_or(&emoji_code).to_string(),
        }
    }

    pub fn from_git2(commit: &git2::Commit) -> Option<Commit> {
        // author
        let author = commit.author();
        let author = author.name().or_else(|| author.email()).unwrap_or("");

        // hash (full, since git2r doesn't support shorthash yet )
        let hash = format!("{}", commit.id());

        // summary and new commit
        let summary = commit.summary().unwrap_or("");
        match RE_SUMMARY.captures(summary) {
            None => None,
            Some(captures) => {
                let emoji_code = captures.get(1).unwrap().as_str();
                let summary = captures.get(2).unwrap().as_str().trim();

                Some(Commit::new(hash, summary, author, emoji_code))
            }
        }
    }

    pub fn from_revwalk(repository: &Repository, revwalk: &mut Revwalk) -> Vec<Commit> {
        revwalk
            .filter_map(|oid| repository.find_commit(oid.unwrap()).ok())
            .filter_map(|raw_commit| Commit::from_git2(&raw_commit))
            .collect()
    }
}