150 lines
4.1 KiB
Rust
150 lines
4.1 KiB
Rust
use std::env;
|
|
use std::collections::HashMap;
|
|
use std::path::PathBuf;
|
|
use std::fs;
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
lazy_static!{
|
|
static ref LOGLEVEL: LogLevel = LogLevel::from_env();
|
|
static ref LANG: String = lang_from_env();
|
|
static ref TRANSLATIONS: HashMap<String, String> = load_translations();
|
|
}
|
|
|
|
pub type Context<'a> = &'a HashMap<&'a str, &'a str>;
|
|
|
|
/// Returns a PathBuf containing the translations. Does not mean
|
|
/// the translations are in there!
|
|
/// First attempts to find $FORGEBUILDI18N from env, otherwise tries
|
|
/// $HOME/.local/share/forgebuild/i18n or /usr/local/share/forgebuild/i18n
|
|
fn find_translations() -> PathBuf {
|
|
match env::var("FORGEBUILDI18N") {
|
|
Ok(dir) => PathBuf::from(dir),
|
|
Err(_) => {
|
|
let home = env::var("HOME").expect("$HOME environment variable is not defined!");
|
|
let mut path = PathBuf::from(home);
|
|
path.push(".local/share/forgebuild/i18n");
|
|
if path.is_dir() {
|
|
path
|
|
} else {
|
|
// Didn't find from env or in home directory,
|
|
// return default /usr/share/local/forgebuild/i18n
|
|
PathBuf::from("/usr/share/local/forgebuild/i18n")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn load_translations() -> HashMap<String, String> {
|
|
let mut path = find_translations();
|
|
if !path.is_dir() {
|
|
panic!("Could not find translations in {:?}", path);
|
|
}
|
|
path.push(format!("{}.json", *LANG));
|
|
|
|
if !path.is_file() {
|
|
panic!("Could not find translation file: {:?}", path);
|
|
}
|
|
|
|
match fs::read_to_string(&path) {
|
|
Ok(content) => {
|
|
//let trans: HashMap<String, String> = serde_json::from_str(&content).expect("Could not load translations");
|
|
//return trans
|
|
match serde_json::from_str(&content) {
|
|
Ok(trans) => trans,
|
|
Err(e) => panic!("JSON ERROR: {}", e)
|
|
}
|
|
},
|
|
Err(e) => {
|
|
panic!("IO ERROR: {}", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn trans(key: &str) -> String {
|
|
match TRANSLATIONS.get(key) {
|
|
Some(t) => t.to_string(),
|
|
None => {
|
|
panic!("Unknown translation string in lang {}: {}", *LANG, key);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn lang_from_env() -> String {
|
|
let lang = env::var("LANG").expect("$LANG not set in environment. Your machine is misconfigured!");
|
|
lang[0..2].to_string()
|
|
}
|
|
|
|
|
|
struct LogLevel {
|
|
info: bool,
|
|
debug: bool,
|
|
error: bool
|
|
}
|
|
|
|
impl LogLevel {
|
|
fn from_env() -> LogLevel {
|
|
// Default values
|
|
let error = true;
|
|
let mut info = true;
|
|
let mut debug = false;
|
|
|
|
let env_log = env::var("LOG").unwrap_or("info".to_string());
|
|
match env_log.to_lowercase().as_str() {
|
|
"info" => {},
|
|
"debug" => { debug = true; },
|
|
"error" => { info = false; }
|
|
_ => {
|
|
// This happens before loglevel initialization
|
|
// so we can't use warn function
|
|
eprintln!("$LOG level is incorrect: {} (can be: debug, info, error", env_log);
|
|
}
|
|
}
|
|
|
|
return LogLevel {
|
|
info,
|
|
debug,
|
|
error
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fn expand(msg: &str, vars: Option<Context>) -> String {
|
|
//let mut s = msg;
|
|
if vars.is_some() {
|
|
return vars.unwrap().iter().fold(msg.to_string(), |prev, (key, val)| {
|
|
prev.replace(key, val)
|
|
})
|
|
}
|
|
return msg.to_string();
|
|
}
|
|
|
|
pub fn info(msg: &str, vars: Option<Context>) {
|
|
if LOGLEVEL.info {
|
|
let t_msg = expand(&trans(msg), vars);
|
|
println!("[git-build] {}", t_msg);
|
|
}
|
|
}
|
|
|
|
pub fn error(msg: &str, vars: Option<Context>) {
|
|
if LOGLEVEL.error {
|
|
let t_msg = expand(&trans(msg), vars);
|
|
eprintln!("{}{}", trans("error"), t_msg);
|
|
}
|
|
}
|
|
|
|
pub fn warn(msg: &str, vars: Option<Context>) {
|
|
if LOGLEVEL.error {
|
|
let t_msg = expand(&trans(msg), vars);
|
|
eprintln!("{}{}", trans("warning"), t_msg);
|
|
}
|
|
}
|
|
|
|
pub fn debug(msg: &str, vars: Option<Context>) {
|
|
if LOGLEVEL.debug {
|
|
let t_msg = expand(&trans(msg), vars);
|
|
println!("{}{}", trans("debug"), t_msg);
|
|
}
|
|
}
|