use std::ffi::OsStr;
fn main() {
match invoked_as().as_deref() {
Some("harn-lsp") => run_sidecar("harn-lsp", harn_lsp::run),
Some("harn-dap") => run_sidecar("harn-dap", harn_dap::run),
_ => harn_cli::run(),
}
}
fn invoked_as() -> Option<String> {
std::env::args_os()
.next()
.as_deref()
.map(std::path::Path::new)
.and_then(std::path::Path::file_stem)
.and_then(|stem| stem.to_str())
.map(str::to_owned)
}
fn run_sidecar(name: &str, serve: fn()) {
match sidecar_query(std::env::args_os().skip(1)) {
Some(SidecarQuery::Version) => println!("{name} {}", env!("CARGO_PKG_VERSION")),
Some(SidecarQuery::Help) => print_sidecar_help(name),
None => serve(),
}
}
#[derive(Debug, PartialEq, Eq)]
enum SidecarQuery {
Version,
Help,
}
fn sidecar_query<I, S>(mut args: I) -> Option<SidecarQuery>
where
I: Iterator<Item = S>,
S: AsRef<OsStr>,
{
match args.next()?.as_ref().to_str()? {
"--version" | "-V" => Some(SidecarQuery::Version),
"--help" | "-h" => Some(SidecarQuery::Help),
_ => None,
}
}
fn print_sidecar_help(name: &str) {
let kind = if name.ends_with("dap") {
"debug adapter (DAP)"
} else {
"language server (LSP)"
};
println!("{name} {}", env!("CARGO_PKG_VERSION"));
println!();
println!("The Harn {kind}. It communicates over stdio and is normally");
println!("launched by an editor rather than run directly.");
println!();
println!("Options:");
println!(" -V, --version Print version and exit");
println!(" -h, --help Print this help and exit");
}
#[cfg(test)]
mod tests {
use super::{sidecar_query, SidecarQuery};
#[test]
fn detects_version_flags() {
assert_eq!(
sidecar_query(["--version"].iter()),
Some(SidecarQuery::Version)
);
assert_eq!(sidecar_query(["-V"].iter()), Some(SidecarQuery::Version));
}
#[test]
fn detects_help_flags() {
assert_eq!(sidecar_query(["--help"].iter()), Some(SidecarQuery::Help));
assert_eq!(sidecar_query(["-h"].iter()), Some(SidecarQuery::Help));
}
#[test]
fn no_args_runs_server() {
let empty: [&str; 0] = [];
assert_eq!(sidecar_query(empty.iter()), None);
}
#[test]
fn unrelated_first_arg_runs_server() {
assert_eq!(sidecar_query(["--stdio"].iter()), None);
assert_eq!(sidecar_query(["serve", "--version"].iter()), None);
}
}