use std::env;
use std::ffi::OsString;
use std::io::{self, Write};
use std::path::Path;
use std::process;
use win_reveal::{
dry_run_setting, Error, Revealer, ShellRevealer, DRY_RUN_VAR, EXIT_USAGE, USAGE,
};
struct DryRunRevealer;
impl Revealer for DryRunRevealer {
fn reveal(&self, path: &Path) -> Result<(), Error> {
println!("would reveal: {}", path.display());
Ok(())
}
}
fn help() -> String {
format!(
"reveal: open a path's containing folder in Windows Explorer and select it.
{USAGE}
The path may be relative (resolved against the current directory) or absolute, and may
contain spaces, CJK characters or commas. It must exist, and it must have a containing
folder — a drive root like D:\\ has none.
options:
-h, --help show this help and exit 0
settings (environment):
REVEAL_DRY_RUN=1|true|yes print the resolved path instead of touching Explorer
(0|false|no|empty means off)
REVEAL_TAB_POLICY=newtab|overwrite
what to do when the folder is already open in a tab
you are not looking at; newtab leaves that tab alone
(default), overwrite navigates the visible tab to it
exit codes:
0 the request was handed to the shell
1 the shell call failed (stderr names the Win32 step and HRESULT)
2 bad input or bad setting value (stderr gives the reason and the usage line)
"
)
}
fn fail(error: &Error) -> ! {
let mut stderr = io::stderr();
let _ = writeln!(stderr, "reveal: {error}");
let _ = writeln!(stderr, "{USAGE}");
let _ = stderr.flush();
process::exit(EXIT_USAGE)
}
fn main() {
let args: Vec<OsString> = env::args_os().skip(1).collect();
if matches!(args.first(), Some(arg) if arg == "--help" || arg == "-h") {
print!("{}", help());
let _ = io::stdout().flush();
return;
}
let revealer: Box<dyn Revealer> = match dry_run_setting(env::var_os(DRY_RUN_VAR)) {
Ok(true) => Box::new(DryRunRevealer),
Ok(false) => Box::new(ShellRevealer),
Err(error) => fail(&error),
};
let cwd = match env::current_dir() {
Ok(cwd) => cwd,
Err(e) => {
eprintln!("reveal: cannot resolve working directory: {e}");
process::exit(EXIT_USAGE);
}
};
let mut stderr = io::stderr();
let code = win_reveal::run(&args, &cwd, revealer.as_ref(), &mut stderr);
let _ = stderr.flush();
let _ = io::stdout().flush();
process::exit(code);
}