use std::ffi::OsString;
pub static ALIASES: &[(&str, &[&str])] = &[
("fetch", &["source", "fetch"]),
("install", &["module", "install"]),
("list", &["source", "list"]),
("resolve", &["module", "resolve"]),
("snap", &["source", "snap"]),
("uninstall", &["module", "uninstall"]),
("upgrade", &["module", "upgrade"]),
];
const OPTIONS_WITH_VALUES: &[&str] = &["--color"];
pub fn resolve(args: &mut Vec<OsString>) {
let mut i = 1; while i < args.len() {
let Some(arg) = args[i].to_str() else {
return; };
if arg == "--" {
return;
}
if arg.starts_with('-') && arg.len() > 1 {
i += if OPTIONS_WITH_VALUES.contains(&arg) {
2
} else {
1
};
continue;
}
if arg == "help" {
i += 1;
continue;
}
if let Some((_, expansion)) = ALIASES.iter().find(|(name, _)| *name == arg) {
args.splice(i..=i, expansion.iter().map(OsString::from));
}
return;
}
}
#[cfg(test)]
mod tests {
use super::*;
fn resolved(args: &[&str]) -> Vec<String> {
let mut args: Vec<OsString> = args.iter().map(OsString::from).collect();
resolve(&mut args);
args.into_iter()
.map(|arg| arg.into_string().unwrap())
.collect()
}
#[test]
fn expands_fetch() {
assert_eq!(
resolved(&["asimov", "fetch", "http://example.org"]),
["asimov", "source", "fetch", "http://example.org"]
);
}
#[test]
fn expands_snap() {
assert_eq!(resolved(&["asimov", "snap"]), ["asimov", "source", "snap"]);
}
#[test]
fn expands_install() {
assert_eq!(
resolved(&["asimov", "install", "serpapi"]),
["asimov", "module", "install", "serpapi"]
);
}
#[test]
fn skips_leading_flags() {
assert_eq!(
resolved(&["asimov", "-d", "--color", "auto", "fetch", "url"]),
["asimov", "-d", "--color", "auto", "source", "fetch", "url"]
);
}
#[test]
fn leaves_non_aliases_untouched() {
assert_eq!(
resolved(&["asimov", "module", "list"]),
["asimov", "module", "list"]
);
}
#[test]
fn only_expands_the_subcommand_position() {
assert_eq!(
resolved(&["asimov", "module", "install", "fetch"]),
["asimov", "module", "install", "fetch"]
);
}
#[test]
fn expands_alias_after_help() {
assert_eq!(
resolved(&["asimov", "help", "fetch"]),
["asimov", "help", "source", "fetch"]
);
assert_eq!(
resolved(&["asimov", "help", "install"]),
["asimov", "help", "module", "install"]
);
}
#[test]
fn leaves_help_for_non_aliases_untouched() {
assert_eq!(resolved(&["asimov", "help"]), ["asimov", "help"]);
assert_eq!(
resolved(&["asimov", "help", "module"]),
["asimov", "help", "module"]
);
}
#[test]
fn ignores_args_after_double_dash() {
assert_eq!(
resolved(&["asimov", "--", "fetch"]),
["asimov", "--", "fetch"]
);
}
}