2024-06-05 14:12:42 -04:00
|
|
|
use std::path::{ Path, PathBuf };
|
2024-05-30 09:03:46 -04:00
|
|
|
|
|
|
|
use pico_args::Arguments;
|
|
|
|
|
2024-06-11 10:05:41 -04:00
|
|
|
// - HELPER -
|
2024-05-30 09:03:46 -04:00
|
|
|
const DRIVE: &str = "/mnt/c/";
|
|
|
|
|
2024-06-11 10:05:41 -04:00
|
|
|
// - ENV -
|
|
|
|
const DISTRO: &str = "WSL_DISTRO_NAME";
|
|
|
|
|
|
|
|
// - FLAGS -
|
2024-06-05 14:12:42 -04:00
|
|
|
const HELP: [&str;2] = [ "-h", "--help" ];
|
2024-06-11 10:05:41 -04:00
|
|
|
const NET_PATH: [&str;2] = [ "-n", "--network-path" ];
|
2024-06-05 14:12:42 -04:00
|
|
|
const NO_SPACES: [&str;2] = [ "-s", "--no-space" ];
|
|
|
|
const QUOTED: [&str;2] = [ "-q", "--quotes" ];
|
2024-06-05 09:57:29 -04:00
|
|
|
|
2024-05-30 09:03:46 -04:00
|
|
|
pub fn main() {
|
|
|
|
let mut args = Arguments::from_env();
|
|
|
|
|
2024-06-05 10:04:44 -04:00
|
|
|
// handle help flag
|
|
|
|
if args.contains(HELP) {
|
|
|
|
help_text();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-06-05 09:57:29 -04:00
|
|
|
// handle quote flag
|
|
|
|
let quotes: &str =
|
|
|
|
if args.contains(QUOTED) {
|
|
|
|
if args.contains(QUOTED) { "\"" } // -qq -> "..." (output with double quotes)
|
|
|
|
else { "'" } // -q -> '...' (output with single quotes)
|
|
|
|
} else { "" }; // _ -> ... (output with no quotes)
|
|
|
|
|
2024-06-11 10:05:41 -04:00
|
|
|
// consume simple flags
|
2024-06-05 14:12:42 -04:00
|
|
|
let no_spaces = args.contains(NO_SPACES);
|
2024-06-11 10:05:41 -04:00
|
|
|
let network_path = args.contains(NET_PATH);
|
2024-06-05 14:12:42 -04:00
|
|
|
|
2024-05-30 09:03:46 -04:00
|
|
|
loop {
|
|
|
|
let next = args.subcommand().unwrap();
|
2024-05-30 10:13:37 -04:00
|
|
|
if let Some(arg) = next {
|
|
|
|
let mut output: String;
|
2024-05-30 15:44:02 -04:00
|
|
|
// canonicalize; windows doesn't recognize symlinks
|
2024-05-30 10:13:37 -04:00
|
|
|
let path = Path::new(&arg).canonicalize();
|
|
|
|
if let Ok(target) = path {
|
|
|
|
output = target.to_string_lossy().to_string();
|
|
|
|
} else {
|
|
|
|
output = arg;
|
2024-05-30 09:03:46 -04:00
|
|
|
}
|
2024-05-30 10:13:37 -04:00
|
|
|
|
2024-06-05 14:12:42 -04:00
|
|
|
// handle no-space flag
|
|
|
|
if no_spaces {
|
|
|
|
let tmp = output.clone();
|
|
|
|
let parts = tmp.split('/');
|
|
|
|
let mut current = PathBuf::new();
|
|
|
|
current.push("/");
|
|
|
|
for part in parts {
|
|
|
|
if part.is_empty() { continue; }
|
|
|
|
let space = part.chars().position(|c| c == ' ');
|
|
|
|
let len = part.len();
|
|
|
|
// if space is found, use short version
|
|
|
|
if let Some(index) = space {
|
|
|
|
// find cut point and make slice
|
|
|
|
let cut = usize::min(len, index).min(6);
|
|
|
|
let replace = &(part[..cut]);
|
|
|
|
|
|
|
|
// determine number for shortening
|
|
|
|
let mut index = 0;
|
|
|
|
let children = current.read_dir();
|
|
|
|
if !children.is_ok() { continue; }
|
|
|
|
|
|
|
|
for child in children.unwrap() {
|
|
|
|
if let Ok(child) = child {
|
|
|
|
let name: String = child.file_name().to_string_lossy().into();
|
|
|
|
// matches increment
|
|
|
|
if name.to_lowercase().starts_with(&replace.to_lowercase()) { index += 1; }
|
|
|
|
// ... and break when we hit the target
|
|
|
|
if name == part { break; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
output = output.replacen(part, &format!("{replace}~{index}"), 1);
|
|
|
|
}
|
|
|
|
current.push(part);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-30 15:44:02 -04:00
|
|
|
// simple C-drive substitution
|
2024-05-30 10:13:37 -04:00
|
|
|
if output.starts_with(DRIVE) {
|
|
|
|
output = output.replace(DRIVE, "C:\\");
|
2024-06-11 10:05:41 -04:00
|
|
|
} else if network_path {
|
|
|
|
let name = std::env::var(DISTRO);
|
|
|
|
if let Ok(name) = name {
|
|
|
|
output = format!("//wsl.localhost/{name}{output}");
|
|
|
|
}
|
2024-05-30 10:13:37 -04:00
|
|
|
}
|
|
|
|
|
2024-05-30 15:44:02 -04:00
|
|
|
// switch out separators
|
2024-05-30 10:13:37 -04:00
|
|
|
output = output.replace("/", "\\");
|
|
|
|
|
2024-05-30 15:44:02 -04:00
|
|
|
// emit to stdout
|
2024-06-05 09:57:29 -04:00
|
|
|
println!("{quotes}{output}{quotes}");
|
2024-05-30 09:03:46 -04:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-06-05 10:04:44 -04:00
|
|
|
pub fn help_text() {
|
|
|
|
println!("path-convert v{}
|
|
|
|
Valerie Wolfe <sleeplessval@gmail.com>
|
|
|
|
Canonicalize and convert Unix paths for DOS programs.
|
|
|
|
|
|
|
|
usage: path-convert [flags] <paths...>
|
|
|
|
|
|
|
|
args:
|
2024-06-05 14:12:42 -04:00
|
|
|
<paths...> one or more paths to convert
|
2024-06-05 10:04:44 -04:00
|
|
|
|
|
|
|
flags:
|
2024-06-05 14:12:42 -04:00
|
|
|
-h, --help show this help text
|
|
|
|
-q, --quotes surround the output strings with quotes (-qq for double quotes)
|
|
|
|
-s, --no-space don't allow paths to have spaces
|
2024-06-05 10:04:44 -04:00
|
|
|
", env!("CARGO_PKG_VERSION"));
|
|
|
|
}
|
2024-05-30 09:03:46 -04:00
|
|
|
|