#![allow(non_upper_case_globals)]
#![forbid(unsafe_code)]
#[macro_use]
extern crate bitflags;
use std::{collections::HashMap, fmt::Debug};
use serde::{de, de::Error as Error_, Deserialize, Serialize};
use serde_json::Value;
pub use url::Url;
type PascalCaseBuf = [u8; 32];
const fn fmt_pascal_case_const(name: &str) -> (PascalCaseBuf, usize) {
let mut buf = [0; 32];
let mut buf_i = 0;
let mut name_i = 0;
let name = name.as_bytes();
while name_i < name.len() {
let first = name[name_i];
name_i += 1;
buf[buf_i] = first;
buf_i += 1;
while name_i < name.len() {
let rest = name[name_i];
name_i += 1;
if rest == b'_' {
break;
}
buf[buf_i] = rest.to_ascii_lowercase();
buf_i += 1;
}
}
(buf, buf_i)
}
fn fmt_pascal_case(f: &mut std::fmt::Formatter<'_>, name: &str) -> std::fmt::Result {
for word in name.split('_') {
let mut chars = word.chars();
let first = chars.next().unwrap();
write!(f, "{}", first)?;
for rest in chars {
write!(f, "{}", rest.to_lowercase())?;
}
}
Ok(())
}
macro_rules! lsp_enum {
(impl $typ: ident { $( $(#[$attr:meta])* pub const $name: ident : $enum_type: ty = $value: expr; )* }) => {
impl $typ {
$(
$(#[$attr])*
pub const $name: $enum_type = $value;
)*
}
impl std::fmt::Debug for $typ {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
$(
Self::$name => crate::fmt_pascal_case(f, stringify!($name)),
)*
_ => write!(f, "{}({})", stringify!($typ), self.0),
}
}
}
impl std::convert::TryFrom<&str> for $typ {
type Error = &'static str;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match () {
$(
_ if {
const X: (crate::PascalCaseBuf, usize) = crate::fmt_pascal_case_const(stringify!($name));
let (buf, len) = X;
&buf[..len] == value.as_bytes()
} => Ok(Self::$name),
)*
_ => Err("unknown enum variant"),
}
}
}
}
}
pub mod error_codes;
pub mod notification;
pub mod request;
mod call_hierarchy;
pub use call_hierarchy::*;
mod code_action;
pub use code_action::*;
mod code_lens;
pub use code_lens::*;
mod color;
pub use color::*;
mod completion;
pub use completion::*;
mod document_diagnostic;
pub use document_diagnostic::*;
mod document_highlight;
pub use document_highlight::*;
mod document_link;
pub use document_link::*;
mod document_symbols;
pub use document_symbols::*;
mod file_operations;
pub use file_operations::*;
mod folding_range;
pub use folding_range::*;
mod formatting;
pub use formatting::*;
mod hover;
pub use hover::*;
mod inlay_hint;
pub use inlay_hint::*;
mod inline_value;
pub use inline_value::*;
mod moniker;
pub use moniker::*;
mod progress;
pub use progress::*;
mod references;
pub use references::*;
mod rename;
pub use rename::*;
pub mod selection_range;
pub use selection_range::*;
mod semantic_tokens;
pub use semantic_tokens::*;
mod signature_help;
pub use signature_help::*;
mod type_hierarchy;
pub use type_hierarchy::*;
mod linked_editing;
pub use linked_editing::*;
mod window;
pub use window::*;
mod workspace_diagnostic;
pub use workspace_diagnostic::*;
mod workspace_folders;
pub use workspace_folders::*;
mod workspace_symbols;
pub use workspace_symbols::*;
pub mod lsif;
mod trace;
pub use trace::*;
#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum NumberOrString {
Number(i32),
String(String),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct CancelParams {
pub id: NumberOrString,
}
pub type LSPAny = serde_json::Value;
pub type LSPObject = serde_json::Map<String, serde_json::Value>;
pub type LSPArray = Vec<serde_json::Value>;
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Default, Deserialize, Serialize)]
pub struct Position {
pub line: u32,
pub character: u32,
}
impl Position {
pub fn new(line: u32, character: u32) -> Position {
Position { line, character }
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Deserialize, Serialize)]
pub struct Range {
pub start: Position,
pub end: Position,
}
impl Range {
pub fn new(start: Position, end: Position) -> Range {
Range { start, end }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct Location {
pub uri: Url,
pub range: Range,
}
impl Location {
pub fn new(uri: Url, range: Range) -> Location {
Location { uri, range }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct LocationLink {
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_selection_range: Option<Range>,
pub target_uri: Url,
pub target_range: Range,
pub target_selection_range: Range,
}
#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]
pub struct PositionEncodingKind(std::borrow::Cow<'static, str>);
impl PositionEncodingKind {
pub const UTF8: PositionEncodingKind = PositionEncodingKind::new("utf-8");
pub const UTF16: PositionEncodingKind = PositionEncodingKind::new("utf-16");
pub const UTF32: PositionEncodingKind = PositionEncodingKind::new("utf-32");
pub const fn new(tag: &'static str) -> Self {
PositionEncodingKind(std::borrow::Cow::Borrowed(tag))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl From<String> for PositionEncodingKind {
fn from(from: String) -> Self {
PositionEncodingKind(std::borrow::Cow::from(from))
}
}
impl From<&'static str> for PositionEncodingKind {
fn from(from: &'static str) -> Self {
PositionEncodingKind::new(from)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Diagnostic {
pub range: Range,
#[serde(skip_serializing_if = "Option::is_none")]
pub severity: Option<DiagnosticSeverity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option<NumberOrString>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_description: Option<CodeDescription>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub related_information: Option<Vec<DiagnosticRelatedInformation>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<DiagnosticTag>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<serde_json::Value>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CodeDescription {
pub href: Url,
}
impl Diagnostic {
pub fn new(
range: Range,
severity: Option<DiagnosticSeverity>,
code: Option<NumberOrString>,
source: Option<String>,
message: String,
related_information: Option<Vec<DiagnosticRelatedInformation>>,
tags: Option<Vec<DiagnosticTag>>,
) -> Diagnostic {
Diagnostic {
range,
severity,
code,
source,
message,
related_information,
tags,
..Diagnostic::default()
}
}
pub fn new_simple(range: Range, message: String) -> Diagnostic {
Self::new(range, None, None, None, message, None, None)
}
pub fn new_with_code_number(
range: Range,
severity: DiagnosticSeverity,
code_number: i32,
source: Option<String>,
message: String,
) -> Diagnostic {
let code = Some(NumberOrString::Number(code_number));
Self::new(range, Some(severity), code, source, message, None, None)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Deserialize, Serialize)]
#[serde(transparent)]
pub struct DiagnosticSeverity(i32);
lsp_enum! {
impl DiagnosticSeverity {
pub const ERROR: DiagnosticSeverity = DiagnosticSeverity(1);
pub const WARNING: DiagnosticSeverity = DiagnosticSeverity(2);
pub const INFORMATION: DiagnosticSeverity = DiagnosticSeverity(3);
pub const HINT: DiagnosticSeverity = DiagnosticSeverity(4);
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct DiagnosticRelatedInformation {
pub location: Location,
pub message: String,
}
#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(transparent)]
pub struct DiagnosticTag(i32);
lsp_enum! {
impl DiagnosticTag {
pub const UNNECESSARY: DiagnosticTag = DiagnosticTag(1);
pub const DEPRECATED: DiagnosticTag = DiagnosticTag(2);
}
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct Command {
pub title: String,
pub command: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option<Vec<Value>>,
}
impl Command {
pub fn new(title: String, command: String, arguments: Option<Vec<Value>>) -> Command {
Command {
title,
command,
arguments,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextEdit {
pub range: Range,
pub new_text: String,
}
impl TextEdit {
pub fn new(range: Range, new_text: String) -> TextEdit {
TextEdit { range, new_text }
}
}
pub type ChangeAnnotationIdentifier = String;
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AnnotatedTextEdit {
#[serde(flatten)]
pub text_edit: TextEdit,
pub annotation_id: ChangeAnnotationIdentifier,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentEdit {
pub text_document: OptionalVersionedTextDocumentIdentifier,
pub edits: Vec<OneOf<TextEdit, AnnotatedTextEdit>>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ChangeAnnotation {
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub needs_confirmation: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ChangeAnnotationWorkspaceEditClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub groups_on_label: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateFileOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub overwrite: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_if_exists: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateFile {
pub uri: Url,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<CreateFileOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub annotation_id: Option<ChangeAnnotationIdentifier>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RenameFileOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub overwrite: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_if_exists: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RenameFile {
pub old_uri: Url,
pub new_uri: Url,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<RenameFileOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub annotation_id: Option<ChangeAnnotationIdentifier>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeleteFileOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub recursive: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_if_not_exists: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub annotation_id: Option<ChangeAnnotationIdentifier>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeleteFile {
pub uri: Url,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<DeleteFileOptions>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceEdit {
#[serde(with = "url_map")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub changes: Option<HashMap<Url, Vec<TextEdit>>>, #[serde(skip_serializing_if = "Option::is_none")]
pub document_changes: Option<DocumentChanges>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change_annotations: Option<HashMap<ChangeAnnotationIdentifier, ChangeAnnotation>>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum DocumentChanges {
Edits(Vec<TextDocumentEdit>),
Operations(Vec<DocumentChangeOperation>),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged, rename_all = "lowercase")]
pub enum DocumentChangeOperation {
Op(ResourceOp),
Edit(TextDocumentEdit),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(tag = "kind", rename_all = "lowercase")]
pub enum ResourceOp {
Create(CreateFile),
Rename(RenameFile),
Delete(DeleteFile),
}
pub type DidChangeConfigurationClientCapabilities = DynamicRegistrationClientCapabilities;
#[derive(Debug, Default, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ConfigurationParams {
pub items: Vec<ConfigurationItem>,
}
#[derive(Debug, Default, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ConfigurationItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub scope_uri: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub section: Option<String>,
}
mod url_map {
use std::fmt;
use std::marker::PhantomData;
use super::*;
pub fn deserialize<'de, D, V>(deserializer: D) -> Result<Option<HashMap<Url, V>>, D::Error>
where
D: serde::Deserializer<'de>,
V: de::DeserializeOwned,
{
struct UrlMapVisitor<V> {
_marker: PhantomData<V>,
}
impl<V: de::DeserializeOwned> Default for UrlMapVisitor<V> {
fn default() -> Self {
UrlMapVisitor {
_marker: PhantomData,
}
}
}
impl<'de, V: de::DeserializeOwned> de::Visitor<'de> for UrlMapVisitor<V> {
type Value = HashMap<Url, V>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("map")
}
fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
where
M: de::MapAccess<'de>,
{
let mut values = HashMap::with_capacity(visitor.size_hint().unwrap_or(0));
while let Some((key, value)) = visitor.next_entry::<Url, _>()? {
values.insert(key, value);
}
Ok(values)
}
}
struct OptionUrlMapVisitor<V> {
_marker: PhantomData<V>,
}
impl<V: de::DeserializeOwned> Default for OptionUrlMapVisitor<V> {
fn default() -> Self {
OptionUrlMapVisitor {
_marker: PhantomData,
}
}
}
impl<'de, V: de::DeserializeOwned> de::Visitor<'de> for OptionUrlMapVisitor<V> {
type Value = Option<HashMap<Url, V>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("option")
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
#[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer
.deserialize_map(UrlMapVisitor::<V>::default())
.map(Some)
}
}
deserializer.deserialize_option(OptionUrlMapVisitor::default())
}
pub fn serialize<S, V>(
changes: &Option<HashMap<Url, V>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
V: serde::Serialize,
{
use serde::ser::SerializeMap;
match *changes {
Some(ref changes) => {
let mut map = serializer.serialize_map(Some(changes.len()))?;
for (k, v) in changes {
map.serialize_entry(k.as_str(), v)?;
}
map.end()
}
None => serializer.serialize_none(),
}
}
}
impl WorkspaceEdit {
pub fn new(changes: HashMap<Url, Vec<TextEdit>>) -> WorkspaceEdit {
WorkspaceEdit {
changes: Some(changes),
document_changes: None,
..Default::default()
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct TextDocumentIdentifier {
pub uri: Url,
}
impl TextDocumentIdentifier {
pub fn new(uri: Url) -> TextDocumentIdentifier {
TextDocumentIdentifier { uri }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentItem {
pub uri: Url,
pub language_id: String,
pub version: i32,
pub text: String,
}
impl TextDocumentItem {
pub fn new(uri: Url, language_id: String, version: i32, text: String) -> TextDocumentItem {
TextDocumentItem {
uri,
language_id,
version,
text,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct VersionedTextDocumentIdentifier {
pub uri: Url,
pub version: i32,
}
impl VersionedTextDocumentIdentifier {
pub fn new(uri: Url, version: i32) -> VersionedTextDocumentIdentifier {
VersionedTextDocumentIdentifier { uri, version }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct OptionalVersionedTextDocumentIdentifier {
pub uri: Url,
pub version: Option<i32>,
}
impl OptionalVersionedTextDocumentIdentifier {
pub fn new(uri: Url, version: i32) -> OptionalVersionedTextDocumentIdentifier {
OptionalVersionedTextDocumentIdentifier {
uri,
version: Some(version),
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentPositionParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
}
impl TextDocumentPositionParams {
pub fn new(
text_document: TextDocumentIdentifier,
position: Position,
) -> TextDocumentPositionParams {
TextDocumentPositionParams {
text_document,
position,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct DocumentFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scheme: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pattern: Option<String>,
}
pub type DocumentSelector = Vec<DocumentFilter>;
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct InitializeParams {
pub process_id: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
#[deprecated(note = "Use `root_uri` instead when possible")]
pub root_path: Option<String>,
#[serde(default)]
pub root_uri: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub initialization_options: Option<Value>,
pub capabilities: ClientCapabilities,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub trace: Option<TraceValue>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_folders: Option<Vec<WorkspaceFolder>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_info: Option<ClientInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub locale: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct ClientInfo {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Copy, Deserialize, Serialize)]
pub struct InitializedParams {}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct GenericRegistrationOptions {
#[serde(flatten)]
pub text_document_registration_options: TextDocumentRegistrationOptions,
#[serde(flatten)]
pub options: GenericOptions,
#[serde(flatten)]
pub static_registration_options: StaticRegistrationOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct GenericOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct GenericParams {
#[serde(flatten)]
pub text_document_position_params: TextDocumentPositionParams,
#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
#[serde(flatten)]
pub partial_result_params: PartialResultParams,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DynamicRegistrationClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GotoCapability {
#[serde(skip_serializing_if = "Option::is_none")]
pub dynamic_registration: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub link_support: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceEditClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub document_changes: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_operations: Option<Vec<ResourceOperationKind>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub failure_handling: Option<FailureHandlingKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub normalizes_line_endings: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change_annotation_support: Option<ChangeAnnotationWorkspaceEditClientCapabilities>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]
#[serde(rename_all = "lowercase")]
pub enum ResourceOperationKind {
Create,
Rename,
Delete,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]
#[serde(rename_all = "camelCase")]
pub enum FailureHandlingKind {
Abort,
Transactional,
TextOnlyTransactional,
Undo,
}
#[derive(Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct SymbolKind(i32);
lsp_enum! {
impl SymbolKind {
pub const FILE: SymbolKind = SymbolKind(1);
pub const MODULE: SymbolKind = SymbolKind(2);
pub const NAMESPACE: SymbolKind = SymbolKind(3);
pub const PACKAGE: SymbolKind = SymbolKind(4);
pub const CLASS: SymbolKind = SymbolKind(5);
pub const METHOD: SymbolKind = SymbolKind(6);
pub const PROPERTY: SymbolKind = SymbolKind(7);
pub const FIELD: SymbolKind = SymbolKind(8);
pub const CONSTRUCTOR: SymbolKind = SymbolKind(9);
pub const ENUM: SymbolKind = SymbolKind(10);
pub const INTERFACE: SymbolKind = SymbolKind(11);
pub const FUNCTION: SymbolKind = SymbolKind(12);
pub const VARIABLE: SymbolKind = SymbolKind(13);
pub const CONSTANT: SymbolKind = SymbolKind(14);
pub const STRING: SymbolKind = SymbolKind(15);
pub const NUMBER: SymbolKind = SymbolKind(16);
pub const BOOLEAN: SymbolKind = SymbolKind(17);
pub const ARRAY: SymbolKind = SymbolKind(18);
pub const OBJECT: SymbolKind = SymbolKind(19);
pub const KEY: SymbolKind = SymbolKind(20);
pub const NULL: SymbolKind = SymbolKind(21);
pub const ENUM_MEMBER: SymbolKind = SymbolKind(22);
pub const STRUCT: SymbolKind = SymbolKind(23);
pub const EVENT: SymbolKind = SymbolKind(24);
pub const OPERATOR: SymbolKind = SymbolKind(25);
pub const TYPE_PARAMETER: SymbolKind = SymbolKind(26);
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SymbolKindCapability {
pub value_set: Option<Vec<SymbolKind>>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub apply_edit: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_edit: Option<WorkspaceEditClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub did_change_configuration: Option<DidChangeConfigurationClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub did_change_watched_files: Option<DidChangeWatchedFilesClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<WorkspaceSymbolClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub execute_command: Option<ExecuteCommandClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_folders: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub configuration: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub semantic_tokens: Option<SemanticTokensWorkspaceClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_lens: Option<CodeLensWorkspaceClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_operations: Option<WorkspaceFileOperationsClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inline_value: Option<InlineValueWorkspaceClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inlay_hint: Option<InlayHintWorkspaceClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub diagnostic: Option<DiagnosticWorkspaceClientCapabilities>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentSyncClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub dynamic_registration: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub will_save: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub will_save_wait_until: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub did_save: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PublishDiagnosticsClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub related_information: Option<bool>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "TagSupport::deserialize_compat"
)]
pub tag_support: Option<TagSupport<DiagnosticTag>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version_support: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_description_support: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data_support: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TagSupport<T> {
pub value_set: Vec<T>,
}
impl<T> TagSupport<T> {
fn deserialize_compat<'de, S>(serializer: S) -> Result<Option<TagSupport<T>>, S::Error>
where
S: serde::Deserializer<'de>,
T: serde::Deserialize<'de>,
{
Ok(
match Option::<Value>::deserialize(serializer).map_err(serde::de::Error::custom)? {
Some(Value::Bool(false)) => None,
Some(Value::Bool(true)) => Some(TagSupport { value_set: vec![] }),
Some(other) => {
Some(TagSupport::<T>::deserialize(other).map_err(serde::de::Error::custom)?)
}
None => None,
},
)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub synchronization: Option<TextDocumentSyncClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion: Option<CompletionClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hover: Option<HoverClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature_help: Option<SignatureHelpClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub references: Option<ReferenceClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_highlight: Option<DocumentHighlightClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_symbol: Option<DocumentSymbolClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub formatting: Option<DocumentFormattingClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub range_formatting: Option<DocumentRangeFormattingClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub on_type_formatting: Option<DocumentOnTypeFormattingClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub declaration: Option<GotoCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub definition: Option<GotoCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub type_definition: Option<GotoCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub implementation: Option<GotoCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_action: Option<CodeActionClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_lens: Option<CodeLensClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_link: Option<DocumentLinkClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub color_provider: Option<DocumentColorClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rename: Option<RenameClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub publish_diagnostics: Option<PublishDiagnosticsClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub folding_range: Option<FoldingRangeClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub selection_range: Option<SelectionRangeClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub linked_editing_range: Option<LinkedEditingRangeClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub call_hierarchy: Option<CallHierarchyClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub semantic_tokens: Option<SemanticTokensClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub moniker: Option<MonikerClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub type_hierarchy: Option<TypeHierarchyClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inline_value: Option<InlineValueClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inlay_hint: Option<InlayHintClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub diagnostic: Option<DiagnosticClientCapabilities>,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace: Option<WorkspaceClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_document: Option<TextDocumentClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub window: Option<WindowClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub general: Option<GeneralClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg(feature = "proposed")]
pub offset_encoding: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub experimental: Option<Value>,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GeneralClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub regular_expressions: Option<RegularExpressionsClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub markdown: Option<MarkdownClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stale_request_support: Option<StaleRequestSupportClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub position_encodings: Option<Vec<PositionEncodingKind>>,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StaleRequestSupportClientCapabilities {
pub cancel: bool,
pub retry_on_content_modified: Vec<String>,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RegularExpressionsClientCapabilities {
pub engine: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MarkdownClientCapabilities {
pub parser: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allowed_tags: Option<Vec<String>>,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeResult {
pub capabilities: ServerCapabilities,
#[serde(skip_serializing_if = "Option::is_none")]
pub server_info: Option<ServerInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg(feature = "proposed")]
pub offset_encoding: Option<String>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct ServerInfo {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct InitializeError {
pub retry: bool,
}
#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]
#[serde(transparent)]
pub struct TextDocumentSyncKind(i32);
lsp_enum! {
impl TextDocumentSyncKind {
pub const NONE: TextDocumentSyncKind = TextDocumentSyncKind(0);
pub const FULL: TextDocumentSyncKind = TextDocumentSyncKind(1);
pub const INCREMENTAL: TextDocumentSyncKind = TextDocumentSyncKind(2);
}
}
pub type ExecuteCommandClientCapabilities = DynamicRegistrationClientCapabilities;
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct ExecuteCommandOptions {
pub commands: Vec<String>,
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SaveOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub include_text: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum TextDocumentSyncSaveOptions {
Supported(bool),
SaveOptions(SaveOptions),
}
impl From<SaveOptions> for TextDocumentSyncSaveOptions {
fn from(from: SaveOptions) -> Self {
Self::SaveOptions(from)
}
}
impl From<bool> for TextDocumentSyncSaveOptions {
fn from(from: bool) -> Self {
Self::Supported(from)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentSyncOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub open_close: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change: Option<TextDocumentSyncKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub will_save: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub will_save_wait_until: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub save: Option<TextDocumentSyncSaveOptions>,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum OneOf<A, B> {
Left(A),
Right(B),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum TextDocumentSyncCapability {
Kind(TextDocumentSyncKind),
Options(TextDocumentSyncOptions),
}
impl From<TextDocumentSyncOptions> for TextDocumentSyncCapability {
fn from(from: TextDocumentSyncOptions) -> Self {
Self::Options(from)
}
}
impl From<TextDocumentSyncKind> for TextDocumentSyncCapability {
fn from(from: TextDocumentSyncKind) -> Self {
Self::Kind(from)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ImplementationProviderCapability {
Simple(bool),
Options(StaticTextDocumentRegistrationOptions),
}
impl From<StaticTextDocumentRegistrationOptions> for ImplementationProviderCapability {
fn from(from: StaticTextDocumentRegistrationOptions) -> Self {
Self::Options(from)
}
}
impl From<bool> for ImplementationProviderCapability {
fn from(from: bool) -> Self {
Self::Simple(from)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum TypeDefinitionProviderCapability {
Simple(bool),
Options(StaticTextDocumentRegistrationOptions),
}
impl From<StaticTextDocumentRegistrationOptions> for TypeDefinitionProviderCapability {
fn from(from: StaticTextDocumentRegistrationOptions) -> Self {
Self::Options(from)
}
}
impl From<bool> for TypeDefinitionProviderCapability {
fn from(from: bool) -> Self {
Self::Simple(from)
}
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub position_encoding: Option<PositionEncodingKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_document_sync: Option<TextDocumentSyncCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub selection_range_provider: Option<SelectionRangeProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hover_provider: Option<HoverProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_provider: Option<CompletionOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature_help_provider: Option<SignatureHelpOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub definition_provider: Option<OneOf<bool, DefinitionOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub type_definition_provider: Option<TypeDefinitionProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub implementation_provider: Option<ImplementationProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub references_provider: Option<OneOf<bool, ReferencesOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_highlight_provider: Option<OneOf<bool, DocumentHighlightOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_symbol_provider: Option<OneOf<bool, DocumentSymbolOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_symbol_provider: Option<OneOf<bool, WorkspaceSymbolOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_action_provider: Option<CodeActionProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_lens_provider: Option<CodeLensOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_formatting_provider: Option<OneOf<bool, DocumentFormattingOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_range_formatting_provider: Option<OneOf<bool, DocumentRangeFormattingOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_on_type_formatting_provider: Option<DocumentOnTypeFormattingOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rename_provider: Option<OneOf<bool, RenameOptions>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_link_provider: Option<DocumentLinkOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub color_provider: Option<ColorProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub folding_range_provider: Option<FoldingRangeProviderCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub declaration_provider: Option<DeclarationCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub execute_command_provider: Option<ExecuteCommandOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace: Option<WorkspaceServerCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub call_hierarchy_provider: Option<CallHierarchyServerCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub semantic_tokens_provider: Option<SemanticTokensServerCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub moniker_provider: Option<OneOf<bool, MonikerServerCapabilities>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub linked_editing_range_provider: Option<LinkedEditingRangeServerCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inline_value_provider: Option<OneOf<bool, InlineValueServerCapabilities>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inlay_hint_provider: Option<OneOf<bool, InlayHintServerCapabilities>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub diagnostic_provider: Option<DiagnosticServerCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub experimental: Option<Value>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_folders: Option<WorkspaceFoldersServerCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_operations: Option<WorkspaceFileOperationsServerCapabilities>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Registration {
pub id: String,
pub method: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub register_options: Option<Value>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct RegistrationParams {
pub registrations: Vec<Registration>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentRegistrationOptions {
pub document_selector: Option<DocumentSelector>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum DeclarationCapability {
Simple(bool),
RegistrationOptions(DeclarationRegistrationOptions),
Options(DeclarationOptions),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeclarationRegistrationOptions {
#[serde(flatten)]
pub declaration_options: DeclarationOptions,
#[serde(flatten)]
pub text_document_registration_options: TextDocumentRegistrationOptions,
#[serde(flatten)]
pub static_registration_options: StaticRegistrationOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeclarationOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StaticRegistrationOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
}
#[derive(Debug, Default, Eq, PartialEq, Clone, Deserialize, Serialize, Copy)]
#[serde(rename_all = "camelCase")]
pub struct WorkDoneProgressOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub work_done_progress: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentFormattingOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentRangeFormattingOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DefinitionOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentSymbolOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ReferencesOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentHighlightOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceSymbolOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
#[serde(skip_serializing_if = "Option::is_none")]
pub resolve_provider: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StaticTextDocumentRegistrationOptions {
pub document_selector: Option<DocumentSelector>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct Unregistration {
pub id: String,
pub method: String,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct UnregistrationParams {
pub unregisterations: Vec<Unregistration>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct DidChangeConfigurationParams {
pub settings: Value,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidOpenTextDocumentParams {
pub text_document: TextDocumentItem,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidChangeTextDocumentParams {
pub text_document: VersionedTextDocumentIdentifier,
pub content_changes: Vec<TextDocumentContentChangeEvent>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentContentChangeEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub range: Option<Range>,
#[serde(skip_serializing_if = "Option::is_none")]
pub range_length: Option<u32>,
pub text: String,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentChangeRegistrationOptions {
pub document_selector: Option<DocumentSelector>,
pub sync_kind: i32,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WillSaveTextDocumentParams {
pub text_document: TextDocumentIdentifier,
pub reason: TextDocumentSaveReason,
}
#[derive(Copy, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(transparent)]
pub struct TextDocumentSaveReason(i32);
lsp_enum! {
impl TextDocumentSaveReason {
pub const MANUAL: TextDocumentSaveReason = TextDocumentSaveReason(1);
pub const AFTER_DELAY: TextDocumentSaveReason = TextDocumentSaveReason(2);
pub const FOCUS_OUT: TextDocumentSaveReason = TextDocumentSaveReason(3);
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidCloseTextDocumentParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidSaveTextDocumentParams {
pub text_document: TextDocumentIdentifier,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentSaveRegistrationOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub include_text: Option<bool>,
#[serde(flatten)]
pub text_document_registration_options: TextDocumentRegistrationOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidChangeWatchedFilesClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub dynamic_registration: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub relative_pattern_support: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct DidChangeWatchedFilesParams {
pub changes: Vec<FileEvent>,
}
#[derive(Eq, PartialEq, Hash, Copy, Clone, Deserialize, Serialize)]
#[serde(transparent)]
pub struct FileChangeType(i32);
lsp_enum! {
impl FileChangeType {
pub const CREATED: FileChangeType = FileChangeType(1);
pub const CHANGED: FileChangeType = FileChangeType(2);
pub const DELETED: FileChangeType = FileChangeType(3);
}
}
#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]
pub struct FileEvent {
pub uri: Url,
#[serde(rename = "type")]
pub typ: FileChangeType,
}
impl FileEvent {
pub fn new(uri: Url, typ: FileChangeType) -> FileEvent {
FileEvent { uri, typ }
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]
pub struct DidChangeWatchedFilesRegistrationOptions {
pub watchers: Vec<FileSystemWatcher>,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FileSystemWatcher {
pub glob_pattern: GlobPattern,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<WatchKind>,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum GlobPattern {
String(Pattern),
Relative(RelativePattern),
}
impl From<Pattern> for GlobPattern {
#[inline]
fn from(from: Pattern) -> Self {
Self::String(from)
}
}
impl From<RelativePattern> for GlobPattern {
#[inline]
fn from(from: RelativePattern) -> Self {
Self::Relative(from)
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RelativePattern {
pub base_uri: OneOf<WorkspaceFolder, Url>,
pub pattern: Pattern,
}
pub type Pattern = String;
bitflags! {
pub struct WatchKind: u8 {
const Create = 1;
const Change = 2;
const Delete = 4;
}
}
impl<'de> serde::Deserialize<'de> for WatchKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let i = u8::deserialize(deserializer)?;
WatchKind::from_bits(i).ok_or_else(|| {
D::Error::invalid_value(de::Unexpected::Unsigned(u64::from(i)), &"Unknown flag")
})
}
}
impl serde::Serialize for WatchKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(self.bits())
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct PublishDiagnosticsParams {
pub uri: Url,
pub diagnostics: Vec<Diagnostic>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<i32>,
}
impl PublishDiagnosticsParams {
pub fn new(
uri: Url,
diagnostics: Vec<Diagnostic>,
version: Option<i32>,
) -> PublishDiagnosticsParams {
PublishDiagnosticsParams {
uri,
diagnostics,
version,
}
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]
#[serde(untagged)]
pub enum Documentation {
String(String),
MarkupContent(MarkupContent),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum MarkedString {
String(String),
LanguageString(LanguageString),
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct LanguageString {
pub language: String,
pub value: String,
}
impl MarkedString {
pub fn from_markdown(markdown: String) -> MarkedString {
MarkedString::String(markdown)
}
pub fn from_language_code(language: String, code_block: String) -> MarkedString {
MarkedString::LanguageString(LanguageString {
language,
value: code_block,
})
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GotoDefinitionParams {
#[serde(flatten)]
pub text_document_position_params: TextDocumentPositionParams,
#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
#[serde(flatten)]
pub partial_result_params: PartialResultParams,
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum GotoDefinitionResponse {
Scalar(Location),
Array(Vec<Location>),
Link(Vec<LocationLink>),
}
impl From<Location> for GotoDefinitionResponse {
fn from(location: Location) -> Self {
GotoDefinitionResponse::Scalar(location)
}
}
impl From<Vec<Location>> for GotoDefinitionResponse {
fn from(locations: Vec<Location>) -> Self {
GotoDefinitionResponse::Array(locations)
}
}
impl From<Vec<LocationLink>> for GotoDefinitionResponse {
fn from(locations: Vec<LocationLink>) -> Self {
GotoDefinitionResponse::Link(locations)
}
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct ExecuteCommandParams {
pub command: String,
#[serde(default)]
pub arguments: Vec<Value>,
#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct ExecuteCommandRegistrationOptions {
pub commands: Vec<String>,
#[serde(flatten)]
pub execute_command_options: ExecuteCommandOptions,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ApplyWorkspaceEditParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
pub edit: WorkspaceEdit,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ApplyWorkspaceEditResponse {
pub applied: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub failure_reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub failed_change: Option<u32>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum MarkupKind {
PlainText,
Markdown,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]
pub struct MarkupContent {
pub kind: MarkupKind,
pub value: String,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PartialResultParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub partial_result_token: Option<ProgressToken>,
}
#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(transparent)]
pub struct SymbolTag(i32);
lsp_enum! {
impl SymbolTag {
pub const DEPRECATED: SymbolTag = SymbolTag(1);
}
}
#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use super::*;
pub(crate) fn test_serialization<SER>(ms: &SER, expected: &str)
where
SER: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,
{
let json_str = serde_json::to_string(ms).unwrap();
assert_eq!(&json_str, expected);
let deserialized: SER = serde_json::from_str(&json_str).unwrap();
assert_eq!(&deserialized, ms);
}
pub(crate) fn test_deserialization<T>(json: &str, expected: &T)
where
T: for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,
{
let value = serde_json::from_str::<T>(json).unwrap();
assert_eq!(&value, expected);
}
#[test]
fn one_of() {
test_serialization(&OneOf::<bool, ()>::Left(true), r#"true"#);
test_serialization(&OneOf::<String, ()>::Left("abcd".into()), r#""abcd""#);
test_serialization(
&OneOf::<String, WorkDoneProgressOptions>::Right(WorkDoneProgressOptions {
work_done_progress: Some(false),
}),
r#"{"workDoneProgress":false}"#,
);
}
#[test]
fn number_or_string() {
test_serialization(&NumberOrString::Number(123), r#"123"#);
test_serialization(&NumberOrString::String("abcd".into()), r#""abcd""#);
}
#[test]
fn marked_string() {
test_serialization(&MarkedString::from_markdown("xxx".into()), r#""xxx""#);
test_serialization(
&MarkedString::from_language_code("lang".into(), "code".into()),
r#"{"language":"lang","value":"code"}"#,
);
}
#[test]
fn language_string() {
test_serialization(
&LanguageString {
language: "LL".into(),
value: "VV".into(),
},
r#"{"language":"LL","value":"VV"}"#,
);
}
#[test]
fn workspace_edit() {
test_serialization(
&WorkspaceEdit {
changes: Some(vec![].into_iter().collect()),
document_changes: None,
..Default::default()
},
r#"{"changes":{}}"#,
);
test_serialization(
&WorkspaceEdit {
changes: None,
document_changes: None,
..Default::default()
},
r#"{}"#,
);
test_serialization(
&WorkspaceEdit {
changes: Some(
vec![(Url::parse("file://test").unwrap(), vec![])]
.into_iter()
.collect(),
),
document_changes: None,
..Default::default()
},
r#"{"changes":{"file://test/":[]}}"#,
);
}
#[test]
fn root_uri_can_be_missing() {
serde_json::from_str::<InitializeParams>(r#"{ "capabilities": {} }"#).unwrap();
}
#[test]
fn test_watch_kind() {
test_serialization(&WatchKind::Create, "1");
test_serialization(&(WatchKind::Create | WatchKind::Change), "3");
test_serialization(
&(WatchKind::Create | WatchKind::Change | WatchKind::Delete),
"7",
);
}
#[test]
fn test_resource_operation_kind() {
test_serialization(
&vec![
ResourceOperationKind::Create,
ResourceOperationKind::Rename,
ResourceOperationKind::Delete,
],
r#"["create","rename","delete"]"#,
);
}
}