use crate::config::CONFIG_FILE;
use crate::error::Result;
use crate::naming::BranchSpec;
use serde::Deserialize;
use std::collections::BTreeMap;
use std::path::Path;
pub const DEFAULT_GITMOJI: &[(&str, &str)] = &[
("feat", ":sparkles:"),
("fix", ":bug:"),
("hotfix", ":ambulance:"),
("docs", ":memo:"),
("test", ":white_check_mark:"),
("refactor", ":recycle:"),
("chore", ":wrench:"),
("perf", ":zap:"),
("ci", ":construction_worker:"),
("build", ":package:"),
];
const UNKNOWN_SHORTCODE: &str = ":question:";
#[derive(Debug, Clone, Default)]
pub struct GitmojiMap {
entries: BTreeMap<String, String>,
}
impl GitmojiMap {
pub fn get(&self, branch_type: &str) -> Option<&str> {
self.entries.get(branch_type).map(String::as_str)
}
pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
self.entries.iter().map(|(k, v)| (k.as_str(), v.as_str()))
}
pub fn insert(&mut self, branch_type: impl Into<String>, shortcode: impl Into<String>) {
self.entries.insert(branch_type.into(), shortcode.into());
}
}
pub fn default_map() -> GitmojiMap {
let mut map = GitmojiMap::default();
for (ty, shortcode) in DEFAULT_GITMOJI {
map.insert(*ty, *shortcode);
}
map
}
pub fn load(repo_root: Option<&Path>) -> Result<GitmojiMap> {
let mut map = default_map();
let Some(root) = repo_root else {
return Ok(map);
};
let path = root.join(CONFIG_FILE);
if !path.exists() {
return Ok(map);
}
let raw = std::fs::read_to_string(&path)?;
let parsed: GitmojiOnlyConfig = toml::from_str(&raw)?;
for (ty, shortcode) in parsed.gitmoji {
map.insert(ty, shortcode);
}
Ok(map)
}
pub fn resolve_prefix(map: &GitmojiMap, branch: &BranchSpec, unicode: bool) -> String {
let shortcode = map.get(&branch.type_).unwrap_or(UNKNOWN_SHORTCODE);
let emoji = if unicode {
shortcode_to_unicode(shortcode)
} else {
shortcode
};
format!("{} {}(#{}):", emoji, branch.type_, branch.issue)
}
pub fn shortcode_to_unicode(shortcode: &str) -> &str {
match shortcode {
":sparkles:" => "โจ",
":bug:" => "๐",
":ambulance:" => "๐",
":memo:" => "๐",
":white_check_mark:" => "โ
",
":recycle:" => "โป",
":wrench:" => "๐ง",
":zap:" => "โก",
":construction_worker:" => "๐ท",
":package:" => "๐ฆ",
":question:" => "โ",
":rocket:" => "๐",
":tada:" => "๐",
":boom:" => "๐ฅ",
":fire:" => "๐ฅ",
":lock:" => "๐",
":closed_lock_with_key:" => "๐",
":key:" => "๐",
":art:" => "๐จ",
":lipstick:" => "๐",
":hammer:" => "๐จ",
":wastebasket:" => "๐",
":truck:" => "๐",
":bookmark:" => "๐",
":pencil2:" => "โ",
":pushpin:" => "๐",
":green_heart:" => "๐",
":rotating_light:" => "๐จ",
":construction:" => "๐ง",
":heavy_plus_sign:" => "โ",
":heavy_minus_sign:" => "โ",
":arrow_up:" => "โฌ",
":arrow_down:" => "โฌ",
":lock_with_ink_pen:" => "๐",
":mag:" => "๐",
":bulb:" => "๐ก",
":poop:" => "๐ฉ",
":rewind:" => "โช",
":twisted_rightwards_arrows:" => "๐",
":alien:" => "๐ฝ",
":seedling:" => "๐ฑ",
":triangular_flag_on_post:" => "๐ฉ",
":bento:" => "๐ฑ",
":busts_in_silhouette:" => "๐ฅ",
":children_crossing:" => "๐ธ",
":building_construction:" => "๐",
":iphone:" => "๐ฑ",
":clown_face:" => "๐คก",
":egg:" => "๐ฅ",
":see_no_evil:" => "๐",
":camera_flash:" => "๐ธ",
":coffin:" => "โฐ",
":test_tube:" => "๐งช",
":necktie:" => "๐",
":stethoscope:" => "๐ฉบ",
":bricks:" => "๐งฑ",
":technologist:" => "๐งโ๐ป",
":money_with_wings:" => "๐ธ",
":thread:" => "๐งต",
":safety_vest:" => "๐ฆบ",
other => other,
}
}
#[derive(Debug, Default, Deserialize)]
struct GitmojiOnlyConfig {
#[serde(default)]
gitmoji: BTreeMap<String, String>,
}