#[cfg(test)]
mod tests {
}
use std::{collections::HashMap, fmt::Display};
use serde::{Serialize, Deserialize, de::Visitor};
type Integer = i64;
type Uinteger = u64;
type Decimal = f64;
#[derive(Debug)]
pub enum LSPAny {
Object(Box<LSPObject>),
Array(Box<LSPArray>),
String(String),
Integer(Integer),
UInteger(Uinteger),
Decimal(Decimal),
Boolean(bool),
Null
}
impl Serialize for LSPAny {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer {
match self {
Self::Object(obj) => obj.serialize(serializer),
Self::Array(arr) => arr.serialize(serializer),
Self::Boolean(b) => serializer.serialize_bool(*b),
Self::Decimal(d) => serializer.serialize_f64(*d),
Self::Integer(i) => serializer.serialize_i64(*i),
Self::String(s) => s.serialize(serializer),
Self::UInteger(ui) => serializer.serialize_u64(*ui),
Self::Null => serializer.serialize_unit()
}
}
}
struct LSPAnyVisitor;
impl<'de> Visitor<'de> for LSPAnyVisitor {
type Value = LSPAny;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("object, array, boolean, decimal, integer, string or null.")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(LSPAny::Boolean(v))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(LSPAny::Decimal(v))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(LSPAny::Integer(v))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(LSPAny::UInteger(v))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(LSPAny::String(String::from(v)))
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(LSPAny::Null)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>, {
let mut v = Box::new(vec![]);
while let Some(element) = seq.next_element()? {
v.push(element);
}
Ok(LSPAny::Array(v))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>, {
let mut m = Box::new(HashMap::new());
while let Some((key, value)) = map.next_entry()? {
m.insert(key, value);
}
Ok(LSPAny::Object(m))
}
}
impl<'de> Deserialize<'de> for LSPAny {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de> {
deserializer.deserialize_any(LSPAnyVisitor)
}
}
type LSPObject = HashMap<String, LSPAny>;
type LSPArray = Vec<LSPAny>;
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum IntegerOrString {
Integer(Integer),
String(String)
}
impl Serialize for IntegerOrString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer {
match self {
Self::Integer(i) => serializer.serialize_i64(*i),
Self::String(s) => s.serialize(serializer),
}
}
}
struct IntegerOrStringVisitor;
impl<'de> Visitor<'de> for IntegerOrStringVisitor {
type Value = IntegerOrString;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("integer or string.")
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(IntegerOrString::Integer(v))
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(IntegerOrString::Integer(v as i64))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(IntegerOrString::String(String::from(v)))
}
}
impl<'de> Deserialize<'de> for IntegerOrString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de> {
deserializer.deserialize_any(IntegerOrStringVisitor)
}
}
impl Display for IntegerOrString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IntegerOrString::Integer(i) => write!(f, "{i}"),
IntegerOrString::String(s) => write!(f, "\"{s}\"")
}
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct RequestMessage<T> {
pub jsonrpc: String,
pub id: IntegerOrString,
pub method: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub params: Option<T>
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ResponseMessage<T> {
pub jsonrpc: String,
pub id: Option<IntegerOrString>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub result: Option<T>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub error: Option<ResponseError>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ResponseError {
pub code: Integer,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub data: Option<LSPAny>
}
pub mod error_codes {
use super::Integer;
pub const PARSE_ERROR: Integer = -32700;
pub const INVALID_REQUEST: Integer = -32600;
pub const METHOD_NOT_FOUND: Integer = -32701;
pub const INVALID_PARAMS: Integer = -32702;
pub const INTERNAL_ERROR: Integer = -32703;
pub const JSONRPC_RESERVED_ERROR_RANGE_START: Integer = -32099;
#[deprecated]
pub const SERVER_ERROR_START: Integer = JSONRPC_RESERVED_ERROR_RANGE_START;
pub const SERVER_NOT_INITIALIZED: Integer = -32002;
pub const UNKNOWN_ERROR_CODE: Integer = -32001;
pub const JSONRPC_RESERVED_ERROR_RANGE_END: Integer = -32000;
#[deprecated]
pub const SERVER_ERROR_END: Integer = JSONRPC_RESERVED_ERROR_RANGE_END;
pub const LSP_RESERVED_ERROR_RANGE_START: Integer = -32899;
pub const REQUEST_FAILED: Integer = -32803;
pub const SERVER_CANCELLED: Integer = -32802;
pub const CONTENT_MODIFIED: Integer = -32801;
pub const REQUEST_CANCELLED: Integer = -32800;
pub const LSP_RESERVED_ERROR_RANGE_END: Integer = -32800;
}
pub type DocumentUri = String;
pub type URI = String;
#[derive(Debug, Serialize, Deserialize)]
pub struct NotificationMessage<T> {
pub jsonrpc: String,
pub method: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub params: Option<T>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CancelParams {
id: IntegerOrString
}
pub type CancelNotification = NotificationMessage<CancelParams>;
pub type ProgressToken = IntegerOrString;
#[derive(Debug, Serialize, Deserialize)]
pub struct ProgressParams<T> {
token: ProgressToken,
value: T
}
pub type ProgressNotification<T> = NotificationMessage<ProgressParams<T>>;
#[derive(Debug, Serialize, Deserialize)]
pub struct RegularExpressionsClientCapabilities {
engine: String,
#[serde(skip_serializing_if = "Option::is_none")]
version: Option<String>
}
pub const EOL: [&str; 3] = ["\n", "\r\n", "\r"];
#[derive(Debug, Serialize, Deserialize)]
pub struct Position {
line: Uinteger,
character: Uinteger
}
#[derive(Debug, Serialize, Deserialize)]
pub enum PositionEncodingKind {
#[serde(rename = "utf-8")]
UTF8,
#[serde(rename = "utf-16")]
UTF16,
#[serde(rename = "utf-32")]
UTF32
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Range {
pub start: Position,
pub end: Position
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ClientInfo {
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
version: Option<String>
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeParams {
pub process_id: Option<Integer>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub client_info: Option<ClientInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub locale: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
#[deprecated = "in favour of root_uri"]
pub root_path: Option<Option<String>>,
#[deprecated = "in favour of workspace_folders"]
pub root_uri: Option<DocumentUri>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub initialization_options: Option<LSPAny>,
pub capabilities: ClientCapabilities,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub trace: Option<TraceValue>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub workspace_folders: Option<Option<Vec<WorkspaceFolder>>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ServerInfo {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub version: Option<String>
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeResult {
pub capabilities: ServerCapabilities,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub server_info: Option<ServerInfo>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct InitializedParams {}
pub type InitializeRequest = RequestMessage<InitializeParams>;
pub type InitializeResponse = ResponseMessage<InitializeResult>;
pub type InitializedNotification = NotificationMessage<InitializedParams>;
#[derive(Debug, Serialize, Deserialize)]
pub struct ClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub workspace: Option<WorkspaceClientCapabilities>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WorkspaceClientCapabilities {
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub enum TraceValue {
Off,
Messages,
Verbose
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WorkspaceFolder {
uri: DocumentUri,
name: String
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SetTraceParams {
pub value: TraceValue
}
pub type SetTraceNotification = NotificationMessage<SetTraceParams>;
#[derive(Debug, Serialize, Deserialize)]
pub struct LogTraceParams {
pub message: String,
#[serde(skip_serializing_if = "Option::is_none ")]
pub verbose: Option<String>
}
pub type LogTraceNotification = NotificationMessage<LogTraceParams>;
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerCapabilities {
}
pub type ShutdownParams = ();
pub type ShutdownResult = ();
pub type ShutdownRequest = RequestMessage<()>;
pub type ShutdownRespons = ResponseMessage<()>;