blob: d7be108e89c00b3a351b9d402169aa67f973e12e [file] [log] [blame]
//! RLS stub.
//!
//! This is a small stub that replaces RLS to alert the user that RLS is no
//! longer available.
use serde_json::Value;
use std::error::Error;
use std::io::BufRead;
use std::io::Write;
const ALERT_MSG: &str = "\
RLS is no longer available as of Rust 1.65.
Consider migrating to rust-analyzer instead.
See https://rust-analyzer.github.io/ for installation instructions.
";
fn main() {
if let Err(e) = run() {
eprintln!("error: {e}");
std::process::exit(1);
}
}
struct Message {
method: Option<String>,
}
fn run() -> Result<(), Box<dyn Error>> {
let mut stdin = std::io::stdin().lock();
let mut stdout = std::io::stdout().lock();
let init = read_message(&mut stdin)?;
if init.method.as_deref() != Some("initialize") {
return Err(format!("expected initialize, got {:?}", init.method).into());
}
// No response, the LSP specification says that `showMessageRequest` may
// be posted before during this phase.
// message_type 1 is "Error"
let alert = serde_json::json!({
"jsonrpc": "2.0",
"id": 1,
"method": "window/showMessageRequest",
"params": {
"message_type": "1",
"message": ALERT_MSG
}
});
write_message_raw(&mut stdout, serde_json::to_string(&alert).unwrap())?;
loop {
let message = read_message(&mut stdin)?;
if message.method.as_deref() == Some("shutdown") {
std::process::exit(0);
}
}
}
fn read_message_raw<R: BufRead>(reader: &mut R) -> Result<String, Box<dyn Error>> {
let mut content_length: usize = 0;
// Read headers.
loop {
let mut line = String::new();
reader.read_line(&mut line)?;
if line.is_empty() {
return Err("remote disconnected".into());
}
if line == "\r\n" {
break;
}
if line.to_lowercase().starts_with("content-length:") {
let value = &line[15..].trim();
content_length = usize::from_str_radix(value, 10)?;
}
}
if content_length == 0 {
return Err("no content-length".into());
}
let mut buffer = vec![0; content_length];
reader.read_exact(&mut buffer)?;
let content = String::from_utf8(buffer)?;
Ok(content)
}
fn read_message<R: BufRead>(reader: &mut R) -> Result<Message, Box<dyn Error>> {
let m = read_message_raw(reader)?;
match serde_json::from_str::<Value>(&m) {
Ok(message) => Ok(Message {
method: message.get("method").and_then(|value| value.as_str().map(String::from)),
}),
Err(e) => Err(format!("failed to parse message {m}\n{e}").into()),
}
}
fn write_message_raw<W: Write>(mut writer: W, output: String) -> Result<(), Box<dyn Error>> {
write!(writer, "Content-Length: {}\r\n\r\n{}", output.len(), output)?;
writer.flush()?;
Ok(())
}