use anyhow::{bail, Result};
use std::path::PathBuf;
use rust_analyzer_mcp::RustAnalyzerMCPServer;
const USAGE: &str = "\
MCP server for rust-analyzer integration.
Usage: rust-analyzer-mcp [--] [WORKSPACE]
Arguments:
[WORKSPACE] Path to the workspace root [default: current directory]
Options:
-h, --help Print help
-V, --version Print version
";
fn main() -> Result<()> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
let mut args = std::env::args_os().skip(1);
let workspace_path = match args.next() {
Some(arg) if arg == "--" => args.next().map(PathBuf::from),
Some(arg) => match arg.to_str() {
Some("--help") | Some("-h") => {
print!("{USAGE}");
return Ok(());
}
Some("--version") | Some("-V") => {
println!("rust-analyzer-mcp {}", env!("CARGO_PKG_VERSION"));
return Ok(());
}
Some(opt) if opt.starts_with('-') => bail!("unknown option '{opt}'\n\n{USAGE}"),
_ => Some(PathBuf::from(arg)),
},
None => None,
};
let workspace_path = workspace_path
.unwrap_or_else(|| std::env::current_dir().expect("Failed to get current directory"));
if let Some(extra) = args.next() {
bail!(
"unexpected extra argument '{}'\n\n{USAGE}",
extra.to_string_lossy()
);
}
let mut server = RustAnalyzerMCPServer::with_workspace(workspace_path);
let runtime = tokio::runtime::Runtime::new()?;
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
runtime.block_on(server.run())
}));
runtime.shutdown_background();
match result {
Ok(result) => result,
Err(panic) => std::panic::resume_unwind(panic),
}
}