/*! | |
Language Server Protocol types for Rust. | |
Based on: <https://microsoft.github.io/language-server-protocol/specification> | |
This library uses the URL crate for parsing URIs. Note that there is | |
some confusion on the meaning of URLs vs URIs: | |
<http://stackoverflow.com/a/28865728/393898>. According to that | |
information, on the classical sense of "URLs", "URLs" are a subset of | |
URIs, But on the modern/new meaning of URLs, they are the same as | |
URIs. The important take-away aspect is that the URL crate should be | |
able to parse any URI, such as `urn:isbn:0451450523`. | |
*/ | |
#![allow(non_upper_case_globals)] | |
#[macro_use] | |
extern crate bitflags; | |
use serde::{Serialize, Deserialize}; | |
use serde_json; | |
use serde_repr::{Serialize_repr, Deserialize_repr}; | |
pub use url::Url; | |
use std::collections::HashMap; | |
use serde::de; | |
use serde::de::Error as Error_; | |
use serde_json::Value; | |
pub mod notification; | |
pub mod request; | |
/* ----------------- Auxiliary types ----------------- */ | |
#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum NumberOrString { | |
Number(u64), | |
String(String), | |
} | |
/* ----------------- Cancel support ----------------- */ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct CancelParams { | |
/// The request id to cancel. | |
pub id: NumberOrString, | |
} | |
/* ----------------- Basic JSON Structures ----------------- */ | |
/// Position in a text document expressed as zero-based line and character offset. | |
/// A position is between two characters like an 'insert' cursor in a editor. | |
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Default, Deserialize, Serialize)] | |
pub struct Position { | |
/// Line position in a document (zero-based). | |
pub line: u64, | |
/// Character offset on a line in a document (zero-based). | |
pub character: u64, | |
} | |
impl Position { | |
pub fn new(line: u64, character: u64) -> Position { | |
Position { | |
line, | |
character, | |
} | |
} | |
} | |
/// A range in a text document expressed as (zero-based) start and end positions. | |
/// A range is comparable to a selection in an editor. Therefore the end position is exclusive. | |
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Deserialize, Serialize)] | |
pub struct Range { | |
/// The range's start position. | |
pub start: Position, | |
/// The range's end position. | |
pub end: Position, | |
} | |
impl Range { | |
pub fn new(start: Position, end: Position) -> Range { | |
Range { | |
start, | |
end, | |
} | |
} | |
} | |
/// Represents a location inside a resource, such as a line inside a text file. | |
#[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, | |
} | |
} | |
} | |
/// Represents a link between a source and a target location. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct LocationLink { | |
/// Span of the origin of this link. | |
/// | |
/// Used as the underlined span for mouse interaction. Defaults to the word range at | |
/// the mouse position. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub origin_selection_range: Option<Range>, | |
/// The target resource identifier of this link. | |
pub target_uri: Url, | |
/// The full target range of this link. | |
pub target_range: Range, | |
/// The span of this link. | |
pub target_selection_range: Range, | |
} | |
/// Represents a diagnostic, such as a compiler error or warning. | |
/// Diagnostic objects are only valid in the scope of a resource. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct Diagnostic { | |
/// The range at which the message applies. | |
pub range: Range, | |
/// The diagnostic's severity. Can be omitted. If omitted it is up to the | |
/// client to interpret diagnostics as error, warning, info or hint. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub severity: Option<DiagnosticSeverity>, | |
/// The diagnostic's code. Can be omitted. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code: Option<NumberOrString>, | |
// code?: number | string; | |
/// A human-readable string describing the source of this | |
/// diagnostic, e.g. 'typescript' or 'super lint'. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub source: Option<String>, | |
/// The diagnostic's message. | |
pub message: String, | |
/// An array of related diagnostic information, e.g. when symbol-names within | |
/// a scope collide all definitions can be marked via this property. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub related_information: Option<Vec<DiagnosticRelatedInformation>>, | |
} | |
impl Diagnostic { | |
pub fn new( | |
range: Range, | |
severity: Option<DiagnosticSeverity>, | |
code: Option<NumberOrString>, | |
source: Option<String>, | |
message: String, | |
related_information: Option<Vec<DiagnosticRelatedInformation>>, | |
) -> Diagnostic { | |
Diagnostic { | |
range, | |
severity, | |
code, | |
source, | |
message, | |
related_information, | |
} | |
} | |
pub fn new_simple(range: Range, message: String) -> Diagnostic { | |
Self::new(range, None, None, None, message, None) | |
} | |
pub fn new_with_code_number( | |
range: Range, | |
severity: DiagnosticSeverity, | |
code_number: u64, | |
source: Option<String>, | |
message: String, | |
) -> Diagnostic { | |
let code = Some(NumberOrString::Number(code_number)); | |
Self::new(range, Some(severity), code, source, message, None) | |
} | |
} | |
/// The protocol currently supports the following diagnostic severities: | |
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)] | |
pub enum DiagnosticSeverity { | |
/// Reports an error. | |
Error = 1, | |
/// Reports a warning. | |
Warning = 2, | |
/// Reports an information. | |
Information = 3, | |
/// Reports a hint. | |
Hint = 4, | |
} | |
/// Represents a related message and source code location for a diagnostic. This | |
/// should be used to point to code locations that cause or related to a | |
/// diagnostics, e.g when duplicating a symbol in a scope. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct DiagnosticRelatedInformation { | |
/// The location of this related diagnostic information. | |
pub location: Location, | |
/// The message of this related diagnostic information. | |
pub message: String, | |
} | |
impl<'de> serde::Deserialize<'de> for DiagnosticSeverity { | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(match u8::deserialize(deserializer)? { | |
1 => DiagnosticSeverity::Error, | |
2 => DiagnosticSeverity::Warning, | |
3 => DiagnosticSeverity::Information, | |
4 => DiagnosticSeverity::Hint, | |
i => { | |
return Err(D::Error::invalid_value( | |
de::Unexpected::Unsigned(u64::from(i)), | |
&"value of 1, 2, 3 or 4", | |
)); | |
} | |
}) | |
} | |
} | |
impl serde::Serialize for DiagnosticSeverity { | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
serializer.serialize_u8(*self as u8) | |
} | |
} | |
/** | |
Represents a reference to a command. Provides a title which will be used to represent a command in the UI. | |
Commands are identitifed using a string identifier and the protocol currently doesn't specify a set of | |
well known commands. So executing a command requires some tool extension code. | |
*/ | |
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] | |
pub struct Command { | |
/// Title of the command, like `save`. | |
pub title: String, | |
/// The identifier of the actual command handler. | |
pub command: String, | |
/// Arguments that the command handler should be | |
/// invoked with. | |
#[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, | |
} | |
} | |
} | |
/// A textual edit applicable to a text document. | |
/// | |
/// If n `TextEdit`s are applied to a text document all text edits describe changes to the initial document version. | |
/// Execution wise text edits should applied from the bottom to the top of the text document. Overlapping text edits | |
/// are not supported. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextEdit { | |
/// The range of the text document to be manipulated. To insert | |
/// text into a document create a range where start === end. | |
pub range: Range, | |
/// The string to be inserted. For delete operations use an | |
/// empty string. | |
pub new_text: String, | |
} | |
impl TextEdit { | |
pub fn new(range: Range, new_text: String) -> TextEdit { | |
TextEdit { | |
range, | |
new_text, | |
} | |
} | |
} | |
/** | |
Describes textual changes on a single text document. The text document is referred to as a | |
`VersionedTextDocumentIdentifier` to allow clients to check the text document version before an | |
edit is applied. A `TextDocumentEdit` describes all changes on a version Si and after they are | |
applied move the document to version Si+1. So the creator of a `TextDocumentEdit` doesn't need to | |
sort the array or do any kind of ordering. However the edits must be non overlapping. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentEdit { | |
/** | |
* The text document to change. | |
*/ | |
pub text_document: VersionedTextDocumentIdentifier, | |
/** | |
* The edits to be applied. | |
*/ | |
pub edits: Vec<TextEdit>, | |
} | |
/** | |
* Options to create a file. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CreateFileOptions { | |
/** | |
* Overwrite existing file. Overwrite wins over `ignoreIfExists` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub overwrite: Option<bool>, | |
/** | |
* Ignore if exists. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub ignore_if_exists: Option<bool>, | |
} | |
/** | |
* Create file operation | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CreateFile { | |
/** | |
* The resource to create. | |
*/ | |
pub uri: Url, | |
/** | |
* Additional options | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub options: Option<CreateFileOptions>, | |
} | |
/** | |
* Rename file options | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct RenameFileOptions { | |
/** | |
* Overwrite target if existing. Overwrite wins over `ignoreIfExists` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub overwrite: Option<bool>, | |
/** | |
* Ignores if target exists. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub ignore_if_exists: Option<bool>, | |
} | |
/** | |
* Rename file operation | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct RenameFile { | |
/** | |
* The old (existing) location. | |
*/ | |
pub old_uri: Url, | |
/** | |
* The new location. | |
*/ | |
pub new_uri: Url, | |
/** | |
* Rename options. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub options: Option<RenameFileOptions>, | |
} | |
/** | |
* Delete file options | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DeleteFileOptions { | |
/** | |
* Delete the content recursively if a folder is denoted. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub recursive: Option<bool>, | |
/** | |
* Ignore the operation if the file doesn't exist. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub ignore_if_not_exists: Option<bool>, | |
} | |
/** | |
* Delete file operation | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DeleteFile { | |
/** | |
* The file to delete. | |
*/ | |
pub uri: Url, | |
/** | |
* Delete options. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub options: Option<DeleteFileOptions>, | |
} | |
/// A workspace edit represents changes to many resources managed in the workspace. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceEdit { | |
/// Holds changes to existing resources. | |
#[serde(with = "url_map")] | |
#[serde(skip_serializing_if = "Option::is_none")] | |
#[serde(default)] | |
pub changes: Option<HashMap<Url, Vec<TextEdit>>>, // changes?: { [uri: string]: TextEdit[]; }; | |
/** | |
* Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes | |
* are either an array of `TextDocumentEdit`s to express changes to n different text documents | |
* where each text document edit addresses a specific version of a text document. Or it can contain | |
* above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations. | |
* | |
* Whether a client supports versioned document edits is expressed via | |
* `workspace.workspaceEdit.documentChanges` client capability. | |
* | |
* If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then | |
* only plain `TextEdit`s using the `changes` property are supported. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_changes: Option<DocumentChanges>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum DocumentChanges { | |
Edits(Vec<TextDocumentEdit>), | |
Operations(Vec<DocumentChangeOperation>), | |
} | |
// TODO: Once https://github.com/serde-rs/serde/issues/912 is solved | |
// we can remove ResourceOp and switch to the following implementation | |
// of DocumentChangeOperation: | |
// | |
// #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
// #[serde(tag = "kind", rename_all="lowercase" )] | |
// pub enum DocumentChangeOperation { | |
// Create(CreateFile), | |
// Rename(RenameFile), | |
// Delete(DeleteFile), | |
// | |
// #[serde(other)] | |
// Edit(TextDocumentEdit), | |
// } | |
#[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), | |
} | |
#[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 { | |
/// The scope to get the configuration section for. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub scope_uri: Option<String>, | |
///The configuration section asked for. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub section: Option<String>, | |
} | |
mod url_map { | |
use super::*; | |
use std::fmt; | |
pub fn deserialize<'de, D>( | |
deserializer: D, | |
) -> Result<Option<HashMap<Url, Vec<TextEdit>>>, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
struct UrlMapVisitor; | |
impl<'de> de::Visitor<'de> for UrlMapVisitor { | |
type Value = HashMap<Url, Vec<TextEdit>>; | |
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 there are entries remaining in the input, add them | |
// into our map. | |
while let Some((key, value)) = visitor.next_entry::<Url, _>()? { | |
values.insert(key, value); | |
} | |
Ok(values) | |
} | |
} | |
struct OptionUrlMapVisitor; | |
impl<'de> de::Visitor<'de> for OptionUrlMapVisitor { | |
type Value = Option<HashMap<Url, Vec<TextEdit>>>; | |
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).map(Some) | |
} | |
} | |
// Instantiate our Visitor and ask the Deserializer to drive | |
// it over the input data, resulting in an instance of MyMap. | |
deserializer.deserialize_option(OptionUrlMapVisitor) | |
} | |
pub fn serialize<S>( | |
changes: &Option<HashMap<Url, Vec<TextEdit>>>, | |
serializer: S, | |
) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
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, | |
} | |
} | |
} | |
/// Text documents are identified using a URI. On the protocol level, URIs are passed as strings. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct TextDocumentIdentifier { | |
// !!!!!! Note: | |
// In the spec VersionedTextDocumentIdentifier extends TextDocumentIdentifier | |
// This modelled by "mixing-in" TextDocumentIdentifier in VersionedTextDocumentIdentifier, | |
// so any changes to this type must be effected in the sub-type as well. | |
/// The text document's URI. | |
pub uri: Url, | |
} | |
impl TextDocumentIdentifier { | |
pub fn new(uri: Url) -> TextDocumentIdentifier { | |
TextDocumentIdentifier { uri } | |
} | |
} | |
/// An item to transfer a text document from the client to the server. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentItem { | |
/// The text document's URI. | |
pub uri: Url, | |
/// The text document's language identifier. | |
pub language_id: String, | |
/// The version number of this document (it will strictly increase after each | |
/// change, including undo/redo). | |
pub version: u64, | |
/// The content of the opened text document. | |
pub text: String, | |
} | |
impl TextDocumentItem { | |
pub fn new(uri: Url, language_id: String, version: u64, text: String) -> TextDocumentItem { | |
TextDocumentItem { | |
uri, | |
language_id, | |
version, | |
text, | |
} | |
} | |
} | |
/// An identifier to denote a specific version of a text document. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct VersionedTextDocumentIdentifier { | |
// This field was "mixed-in" from TextDocumentIdentifier | |
/// The text document's URI. | |
pub uri: Url, | |
/// The version number of this document. | |
pub version: Option<u64>, | |
} | |
impl VersionedTextDocumentIdentifier { | |
pub fn new(uri: Url, version: u64) -> VersionedTextDocumentIdentifier { | |
VersionedTextDocumentIdentifier { | |
uri, | |
version: Some(version), | |
} | |
} | |
} | |
/// A parameter literal used in requests to pass a text document and a position inside that document. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentPositionParams { | |
// !!!!!! Note: | |
// In the spec ReferenceParams extends TextDocumentPositionParams | |
// This modelled by "mixing-in" TextDocumentPositionParams in ReferenceParams, | |
// so any changes to this type must be effected in sub-type as well. | |
/// The text document. | |
pub text_document: TextDocumentIdentifier, | |
/// The position inside the text document. | |
pub position: Position, | |
} | |
impl TextDocumentPositionParams { | |
pub fn new( | |
text_document: TextDocumentIdentifier, | |
position: Position, | |
) -> TextDocumentPositionParams { | |
TextDocumentPositionParams { | |
text_document, | |
position, | |
} | |
} | |
} | |
/// A document filter denotes a document through properties like language, schema or pattern. | |
/// Examples are a filter that applies to TypeScript files on disk or a filter the applies to JSON | |
/// files with name package.json: | |
/// | |
/// { language: 'typescript', scheme: 'file' } | |
/// { language: 'json', pattern: '**/package.json' } | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct DocumentFilter { | |
/** | |
* A language id, like `typescript`. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub language: Option<String>, | |
/** | |
* A Uri [scheme](#Uri.scheme), like `file` or `untitled`. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub scheme: Option<String>, | |
/** | |
* A glob pattern, like `*.{ts,js}`. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub pattern: Option<String>, | |
} | |
/// A document selector is the combination of one or many document filters. | |
pub type DocumentSelector = Vec<DocumentFilter>; | |
// ========================= Actual Protocol ========================= | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct InitializeParams { | |
/// The process Id of the parent process that started | |
/// the server. Is null if the process has not been started by another process. | |
/// If the parent process is not alive then the server should exit (see exit notification) its process. | |
pub process_id: Option<u64>, | |
/// The rootPath of the workspace. Is null | |
/// if no folder is open. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub root_path: Option<String>, | |
/// The rootUri of the workspace. Is null if no | |
/// folder is open. If both `rootPath` and `rootUri` are set | |
/// `rootUri` wins. | |
#[serde(default)] | |
pub root_uri: Option<Url>, | |
/// User provided initialization options. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub initialization_options: Option<Value>, | |
/// The capabilities provided by the client (editor) | |
pub capabilities: ClientCapabilities, | |
/// The initial trace setting. If omitted trace is disabled ('off'). | |
#[serde(default)] | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub trace: Option<TraceOption>, | |
/// The workspace folders configured in the client when the server starts. | |
/// This property is only available if the client supports workspace folders. | |
/// It can be `null` if the client supports workspace folders but none are | |
/// configured. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace_folders: Option<Vec<WorkspaceFolder>>, | |
} | |
#[derive(Debug, PartialEq, Clone, Copy, Deserialize, Serialize)] | |
pub struct InitializedParams {} | |
#[derive(Debug, Eq, PartialEq, Clone, Copy, Deserialize, Serialize)] | |
pub enum TraceOption { | |
#[serde(rename = "off")] | |
Off, | |
#[serde(rename = "messages")] | |
Messages, | |
#[serde(rename = "verbose")] | |
Verbose, | |
} | |
impl Default for TraceOption { | |
fn default() -> TraceOption { | |
TraceOption::Off | |
} | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct GenericCapability { | |
/** | |
* This capability supports dynamic registration. | |
*/ | |
#[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>, | |
/// The client supports additional metadata in the form of definition links. | |
pub link_support: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceEditCapability { | |
/** | |
* The client supports versioned document changes in `WorkspaceEdit`s | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_changes: Option<bool>, | |
/** | |
* The resource operations the client supports. Clients should at least | |
* support 'create', 'rename' and 'delete' files and folders. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub resource_operations: Option<Vec<ResourceOperationKind>>, | |
/** | |
* The failure handling strategy of a client if applying the workspace edit | |
* failes. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub failure_handling: Option<FailureHandlingKind>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceCapability { | |
/// The server supports workspace folder. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace_folders: Option<WorkspaceFolderCapability>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceFolderCapability { | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub supported: Option<bool>, | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub change_notifications: Option<WorkspaceFolderCapabilityChangeNotifications>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum WorkspaceFolderCapabilityChangeNotifications { | |
Bool(bool), | |
Id(String), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceFolder { | |
/// The associated URI for this workspace folder. | |
pub uri: Url, | |
/// The name of the workspace folder. Defaults to the uri's basename. | |
pub name: String, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DidChangeWorkspaceFoldersParams { | |
/** | |
* The actual workspace folder change event. | |
*/ | |
pub event: WorkspaceFoldersChangeEvent, | |
} | |
/** | |
* The workspace folder change event. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceFoldersChangeEvent { | |
/** | |
* The array of added workspace folders | |
*/ | |
pub added: Vec<WorkspaceFolder>, | |
/** | |
* The array of the removed workspace folders | |
*/ | |
pub removed: Vec<WorkspaceFolder>, | |
} | |
#[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, | |
} | |
/** | |
* Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SymbolKindCapability { | |
/** | |
* The symbol kind values the client supports. When this | |
* property exists the client also guarantees that it will | |
* handle values outside its set gracefully and falls back | |
* to a default value when unknown. | |
* | |
* If this property is not present the client only supports | |
* the symbol kinds from `File` to `Array` as defined in | |
* the initial version of the protocol. | |
*/ | |
pub value_set: Option<Vec<SymbolKind>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SymbolCapability { | |
/** | |
* This capability supports dynamic registration. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/** | |
* Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub symbol_kind: Option<SymbolKindCapability>, | |
} | |
/** | |
* Workspace specific client capabilities. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WorkspaceClientCapabilities { | |
/** | |
* The client supports applying batch edits to the workspace by supporting | |
* the request 'workspace/applyEdit' | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub apply_edit: Option<bool>, | |
/** | |
* Capabilities specific to `WorkspaceEdit`s | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace_edit: Option<WorkspaceEditCapability>, | |
/** | |
* Capabilities specific to the `workspace/didChangeConfiguration` notification. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub did_change_configuration: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `workspace/didChangeWatchedFiles` notification. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub did_change_watched_files: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `workspace/symbol` request. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub symbol: Option<SymbolCapability>, | |
/** | |
* Capabilities specific to the `workspace/executeCommand` request. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub execute_command: Option<GenericCapability>, | |
/** | |
* The client has support for workspace folders. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace_folders: Option<bool>, | |
/** | |
* The client supports `workspace/configuration` requests. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub configuration: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SynchronizationCapability { | |
/** | |
* Whether text document synchronization supports dynamic registration. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/** | |
* The client supports sending will save notifications. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub will_save: Option<bool>, | |
/** | |
* The client supports sending a will save request and | |
* waits for a response providing text edits which will | |
* be applied to the document before it is saved. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub will_save_wait_until: Option<bool>, | |
/** | |
* The client supports did save notifications. | |
*/ | |
#[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 CompletionItemCapability { | |
/** | |
* Client supports snippets as insert text. | |
* | |
* A snippet can define tab stops and placeholders with `$1`, `$2` | |
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to | |
* the end of the snippet. Placeholders with equal identifiers are linked, | |
* that is typing in one will update others too. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub snippet_support: Option<bool>, | |
/** | |
* Client supports commit characters on a completion item. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub commit_characters_support: Option<bool>, | |
/** | |
* Client supports the follow content formats for the documentation | |
* property. The order describes the preferred format of the client. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub documentation_format: Option<Vec<MarkupKind>>, | |
/** | |
* Client supports the deprecated property on a completion item. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub deprecated_support: Option<bool>, | |
/** | |
* Client supports the preselect property on a completion item. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub preselect_support: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionItemKindCapability { | |
/** | |
* The completion item kind values the client supports. When this | |
* property exists the client also guarantees that it will | |
* handle values outside its set gracefully and falls back | |
* to a default value when unknown. | |
* | |
* If this property is not present the client only supports | |
* the completion items kinds from `Text` to `Reference` as defined in | |
* the initial version of the protocol. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub value_set: Option<Vec<CompletionItemKind>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct HoverCapability { | |
/** | |
* Whether completion supports dynamic registration. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/** | |
* Client supports the follow content formats for the content | |
* property. The order describes the preferred format of the client. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub content_format: Option<Vec<MarkupKind>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionCapability { | |
/** | |
* Whether completion supports dynamic registration. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/** | |
* The client supports the following `CompletionItem` specific | |
* capabilities. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub completion_item: Option<CompletionItemCapability>, | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub completion_item_kind: Option<CompletionItemKindCapability>, | |
/** | |
* The client supports to send additional context information for a | |
* `textDocument/completion` requestion. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub context_support: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SignatureInformationSettings { | |
/** | |
* Client supports the follow content formats for the documentation | |
* property. The order describes the preferred format of the client. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub documentation_format: Option<Vec<MarkupKind>>, | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub parameter_information: Option<ParameterInformationSettings>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ParameterInformationSettings { | |
/** | |
* The client supports processing label offsets instead of a | |
* simple label string. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub label_offset_support: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SignatureHelpCapability { | |
/** | |
* Whether completion supports dynamic registration. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/** | |
* The client supports the following `SignatureInformation` | |
* specific properties. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub signature_information: Option<SignatureInformationSettings>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct PublishDiagnosticsCapability { | |
/** | |
* Whether the clients accepts diagnostics with related information. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub related_information: Option<bool>, | |
} | |
/** | |
* Text document specific client capabilities. | |
*/ | |
#[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<SynchronizationCapability>, | |
/** | |
* Capabilities specific to the `textDocument/completion` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub completion: Option<CompletionCapability>, | |
/** | |
* Capabilities specific to the `textDocument/hover` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub hover: Option<HoverCapability>, | |
/** | |
* Capabilities specific to the `textDocument/signatureHelp` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub signature_help: Option<SignatureHelpCapability>, | |
/** | |
* Capabilities specific to the `textDocument/references` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub references: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/documentHighlight` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_highlight: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/documentSymbol` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_symbol: Option<DocumentSymbolCapability>, | |
/** | |
* Capabilities specific to the `textDocument/formatting` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub formatting: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/rangeFormatting` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub range_formatting: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/onTypeFormatting` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub on_type_formatting: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/declaration` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub declaration: Option<GotoCapability>, | |
/** | |
* Capabilities specific to the `textDocument/definition` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub definition: Option<GotoCapability>, | |
/** | |
* Capabilities specific to the `textDocument/typeDefinition` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub type_definition: Option<GotoCapability>, | |
/** | |
* Capabilities specific to the `textDocument/implementation` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub implementation: Option<GotoCapability>, | |
/** | |
* Capabilities specific to the `textDocument/codeAction` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code_action: Option<CodeActionCapability>, | |
/** | |
* Capabilities specific to the `textDocument/codeLens` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code_lens: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/documentLink` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_link: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/documentColor` and the | |
* `textDocument/colorPresentation` request. | |
*/ | |
pub color_provider: Option<GenericCapability>, | |
/** | |
* Capabilities specific to the `textDocument/rename` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub rename: Option<RenameCapability>, | |
/** | |
* Capabilities specific to `textDocument/publishDiagnostics`. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub publish_diagnostics: Option<PublishDiagnosticsCapability>, | |
/** | |
* Capabilities specific to `textDocument/foldingRange` requests. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub folding_range: Option<FoldingRangeCapability>, | |
} | |
/** | |
* Window specific client capabilities. | |
*/ | |
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WindowClientCapabilities { | |
/** | |
* Whether `window/progress` server notifications are supported. | |
*/ | |
#[cfg(feature = "proposed")] | |
pub progress: Option<bool>, | |
} | |
/** | |
* Where ClientCapabilities are currently empty: | |
*/ | |
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ClientCapabilities { | |
/** | |
* Workspace specific client capabilities. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace: Option<WorkspaceClientCapabilities>, | |
/** | |
* Text document specific client capabilities. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub text_document: Option<TextDocumentClientCapabilities>, | |
/** | |
* Window specific client capabilities. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub window: Option<WindowClientCapabilities>, | |
/** | |
* Experimental client capabilities. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub experimental: Option<Value>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
pub struct InitializeResult { | |
/// The capabilities the language server provides. | |
pub capabilities: ServerCapabilities, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
pub struct InitializeError { | |
/// Indicates whether the client should retry to send the | |
/// initilize request after showing the message provided | |
/// in the ResponseError. | |
pub retry: bool, | |
} | |
// The server can signal the following capabilities: | |
/// Defines how the host (editor) should sync document changes to the language server. | |
#[derive(Debug, Eq, PartialEq, Clone, Copy)] | |
pub enum TextDocumentSyncKind { | |
/// Documents should not be synced at all. | |
None = 0, | |
/// Documents are synced by always sending the full content of the document. | |
Full = 1, | |
/// Documents are synced by sending the full content on open. After that only | |
/// incremental updates to the document are sent. | |
Incremental = 2, | |
} | |
impl<'de> serde::Deserialize<'de> for TextDocumentSyncKind { | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(match u8::deserialize(deserializer)? { | |
0 => TextDocumentSyncKind::None, | |
1 => TextDocumentSyncKind::Full, | |
2 => TextDocumentSyncKind::Incremental, | |
i => { | |
return Err(D::Error::invalid_value( | |
de::Unexpected::Unsigned(u64::from(i)), | |
&"value between 0 and 2 (inclusive)", | |
)); | |
} | |
}) | |
} | |
} | |
impl serde::Serialize for TextDocumentSyncKind { | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
serializer.serialize_u8(*self as u8) | |
} | |
} | |
/// Completion options. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionOptions { | |
/// The server provides support to resolve additional information for a completion item. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub resolve_provider: Option<bool>, | |
/// The characters that trigger completion automatically. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub trigger_characters: Option<Vec<String>>, | |
} | |
/// Signature help options. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SignatureHelpOptions { | |
/// The characters that trigger signature help automatically. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub trigger_characters: Option<Vec<String>>, | |
} | |
/// Code Lens options. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeLensOptions { | |
/// Code lens has a resolve provider as well. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub resolve_provider: Option<bool>, | |
} | |
/// Format document on type options | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentOnTypeFormattingOptions { | |
/// A character on which formatting should be triggered, like `}`. | |
pub first_trigger_character: String, | |
/// More trigger characters. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub more_trigger_character: Option<Vec<String>>, | |
} | |
/// Execute command options. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
pub struct ExecuteCommandOptions { | |
/// The commands to be executed on the server | |
pub commands: Vec<String>, | |
} | |
/** | |
* Save options. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SaveOptions { | |
/** | |
* The client is supposed to include the content on save. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub include_text: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentSyncOptions { | |
/** | |
* Open and close notifications are sent to the server. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub open_close: Option<bool>, | |
/** | |
* Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full | |
* and TextDocumentSyncKindIncremental. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub change: Option<TextDocumentSyncKind>, | |
/** | |
* Will save notifications are sent to the server. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub will_save: Option<bool>, | |
/** | |
* Will save wait until requests are sent to the server. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub will_save_wait_until: Option<bool>, | |
/** | |
* Save notifications are sent to the server. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub save: Option<SaveOptions>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum TextDocumentSyncCapability { | |
Kind(TextDocumentSyncKind), | |
Options(TextDocumentSyncOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum ImplementationProviderCapability { | |
Simple(bool), | |
Options(StaticTextDocumentRegistrationOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum TypeDefinitionProviderCapability { | |
Simple(bool), | |
Options(StaticTextDocumentRegistrationOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum ColorProviderCapability { | |
Simple(bool), | |
ColorProvider(ColorProviderOptions), | |
Options(StaticTextDocumentColorProviderOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum CodeActionProviderCapability { | |
Simple(bool), | |
Options(CodeActionOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeActionCapability { | |
/// | |
/// This capability supports dynamic registration. | |
/// | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/// The client support code action literals as a valid | |
/// response of the `textDocument/codeAction` request. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code_action_literal_support: Option<CodeActionLiteralSupport>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeActionLiteralSupport { | |
/// The code action kind is support with the following value set. | |
pub code_action_kind: CodeActionKindLiteralSupport, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeActionKindLiteralSupport { | |
/// The code action kind values the client supports. When this | |
/// property exists the client also guarantees that it will | |
/// handle values outside its set gracefully and falls back | |
/// to a default value when unknown. | |
pub value_set: Vec<String>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ServerCapabilities { | |
/// Defines how text documents are synced. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub text_document_sync: Option<TextDocumentSyncCapability>, | |
/// Capabilities specific to `textDocument/selectionRange` requests. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
#[cfg(feature = "proposed")] | |
pub selection_range_provider: Option<GenericCapability>, | |
/// The server provides hover support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub hover_provider: Option<bool>, | |
/// The server provides completion support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub completion_provider: Option<CompletionOptions>, | |
/// The server provides signature help support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub signature_help_provider: Option<SignatureHelpOptions>, | |
/// The server provides goto definition support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub definition_provider: Option<bool>, | |
/// The server provides goto type definition support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub type_definition_provider: Option<TypeDefinitionProviderCapability>, | |
/// the server provides goto implementation support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub implementation_provider: Option<ImplementationProviderCapability>, | |
/// The server provides find references support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub references_provider: Option<bool>, | |
/// The server provides document highlight support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_highlight_provider: Option<bool>, | |
/// The server provides document symbol support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_symbol_provider: Option<bool>, | |
/// The server provides workspace symbol support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace_symbol_provider: Option<bool>, | |
/// The server provides code actions. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code_action_provider: Option<CodeActionProviderCapability>, | |
/// The server provides code lens. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code_lens_provider: Option<CodeLensOptions>, | |
/// The server provides document formatting. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_formatting_provider: Option<bool>, | |
/// The server provides document range formatting. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_range_formatting_provider: Option<bool>, | |
/// The server provides document formatting on typing. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub document_on_type_formatting_provider: Option<DocumentOnTypeFormattingOptions>, | |
/// The server provides rename support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub rename_provider: Option<RenameProviderCapability>, | |
/// The server provides color provider support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub color_provider: Option<ColorProviderCapability>, | |
/// The server provides folding provider support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub folding_range_provider: Option<FoldingRangeProviderCapability>, | |
/// The server provides execute command support. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub execute_command_provider: Option<ExecuteCommandOptions>, | |
/// Workspace specific server capabilities | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub workspace: Option<WorkspaceCapability>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ShowMessageParams { | |
/// The message type. See {@link MessageType}. | |
#[serde(rename = "type")] | |
pub typ: MessageType, | |
/// The actual message. | |
pub message: String, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Copy)] | |
pub enum MessageType { | |
/// An error message. | |
Error = 1, | |
/// A warning message. | |
Warning = 2, | |
/// An information message. | |
Info = 3, | |
/// A log message. | |
Log = 4, | |
} | |
impl<'de> serde::Deserialize<'de> for MessageType { | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(match u8::deserialize(deserializer)? { | |
1 => MessageType::Error, | |
2 => MessageType::Warning, | |
3 => MessageType::Info, | |
4 => MessageType::Log, | |
i => { | |
return Err(D::Error::invalid_value( | |
de::Unexpected::Unsigned(u64::from(i)), | |
&"value of 1, 2, 3 or 4", | |
)); | |
} | |
}) | |
} | |
} | |
impl serde::Serialize for MessageType { | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
serializer.serialize_u8(*self as u8) | |
} | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ShowMessageRequestParams { | |
/// The message type. See {@link MessageType} | |
#[serde(rename = "type")] | |
pub typ: MessageType, | |
/// The actual message | |
pub message: String, | |
/// The message action items to present. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub actions: Option<Vec<MessageActionItem>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct MessageActionItem { | |
/// A short title like 'Retry', 'Open Log' etc. | |
pub title: String, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct LogMessageParams { | |
/// The message type. See {@link MessageType} | |
#[serde(rename = "type")] | |
pub typ: MessageType, | |
/// The actual message | |
pub message: String, | |
} | |
/** | |
* General parameters to to register for a capability. | |
*/ | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct Registration { | |
/** | |
* The id used to register the request. The id can be used to deregister | |
* the request again. | |
*/ | |
pub id: String, | |
/** | |
* The method / capability to register for. | |
*/ | |
pub method: String, | |
/** | |
* Options necessary for the registration. | |
*/ | |
#[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>, | |
} | |
/// Since most of the registration options require to specify a document selector there is a base | |
/// interface that can be used. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentRegistrationOptions { | |
/** | |
* A document selector to identify the scope of the registration. If set to null | |
* the document selector provided on the client side will be used. | |
*/ | |
pub document_selector: Option<DocumentSelector>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct StaticRegistrationOptions { | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub id: Option<String>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct StaticTextDocumentRegistrationOptions { | |
/** | |
* A document selector to identify the scope of the registration. If set to null | |
* the document selector provided on the client side will be used. | |
*/ | |
pub document_selector: Option<DocumentSelector>, | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub id: Option<String>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ColorProviderOptions {} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct StaticTextDocumentColorProviderOptions { | |
/** | |
* A document selector to identify the scope of the registration. If set to null | |
* the document selector provided on the client side will be used. | |
*/ | |
pub document_selector: Option<DocumentSelector>, | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub id: Option<String>, | |
} | |
/** | |
* General parameters to unregister a capability. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct Unregistration { | |
/** | |
* The id used to unregister the request or notification. Usually an id | |
* provided during the register request. | |
*/ | |
pub id: String, | |
/** | |
* The method / capability to unregister for. | |
*/ | |
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 { | |
/// The actual changed settings | |
pub settings: Value, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DidOpenTextDocumentParams { | |
/// The document that was opened. | |
pub text_document: TextDocumentItem, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DidChangeTextDocumentParams { | |
/// The document that did change. The version number points | |
/// to the version after all provided content changes have | |
/// been applied. | |
pub text_document: VersionedTextDocumentIdentifier, | |
/// The actual content changes. | |
pub content_changes: Vec<TextDocumentContentChangeEvent>, | |
} | |
/// An event describing a change to a text document. If range and rangeLength are omitted | |
/// the new text is considered to be the full content of the document. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentContentChangeEvent { | |
/// The range of the document that changed. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub range: Option<Range>, | |
/// The length of the range that got replaced. | |
/// NOTE: seems redundant, see: <https://github.com/Microsoft/language-server-protocol/issues/9> | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub range_length: Option<u64>, | |
/// The new text of the document. | |
pub text: String, | |
} | |
/** | |
* Descibe options to be used when registered for text document change events. | |
* | |
* Extends TextDocumentRegistrationOptions | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct TextDocumentChangeRegistrationOptions { | |
/** | |
* A document selector to identify the scope of the registration. If set to null | |
* the document selector provided on the client side will be used. | |
*/ | |
pub document_selector: Option<DocumentSelector>, | |
/** | |
* How documents are synced to the server. See TextDocumentSyncKind.Full | |
* and TextDocumentSyncKindIncremental. | |
*/ | |
pub sync_kind: i32, | |
} | |
/** | |
* The parameters send in a will save text document notification. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct WillSaveTextDocumentParams { | |
/** | |
* The document that will be saved. | |
*/ | |
pub text_document: TextDocumentIdentifier, | |
/** | |
* The 'TextDocumentSaveReason'. | |
*/ | |
pub reason: TextDocumentSaveReason, | |
} | |
/** | |
* Represents reasons why a text document is saved. | |
*/ | |
#[derive(Copy, Debug, Eq, PartialEq, Clone)] | |
pub enum TextDocumentSaveReason { | |
/** | |
* Manually triggered, e.g. by the user pressing save, by starting debugging, | |
* or by an API call. | |
*/ | |
Manual = 1, | |
/** | |
* Automatic after a delay. | |
*/ | |
AfterDelay = 2, | |
/** | |
* When the editor lost focus. | |
*/ | |
FocusOut = 3, | |
} | |
impl<'de> serde::Deserialize<'de> for TextDocumentSaveReason { | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(match u8::deserialize(deserializer)? { | |
1 => TextDocumentSaveReason::Manual, | |
2 => TextDocumentSaveReason::AfterDelay, | |
3 => TextDocumentSaveReason::FocusOut, | |
i => { | |
return Err(D::Error::invalid_value( | |
de::Unexpected::Unsigned(u64::from(i)), | |
&"value of 1, 2 or 3", | |
)) | |
} | |
}) | |
} | |
} | |
impl serde::Serialize for TextDocumentSaveReason { | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
serializer.serialize_u8(*self as u8) | |
} | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DidCloseTextDocumentParams { | |
/// The document that was closed. | |
pub text_document: TextDocumentIdentifier, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DidSaveTextDocumentParams { | |
/// The document that was saved. | |
pub text_document: TextDocumentIdentifier, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct DidChangeWatchedFilesParams { | |
/// The actual file events. | |
pub changes: Vec<FileEvent>, | |
} | |
/// The file event type. | |
#[derive(Debug, Eq, PartialEq, Copy, Clone)] | |
pub enum FileChangeType { | |
/// The file got created. | |
Created = 1, | |
/// The file got changed. | |
Changed = 2, | |
/// The file got deleted. | |
Deleted = 3, | |
} | |
impl<'de> serde::Deserialize<'de> for FileChangeType { | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(match u8::deserialize(deserializer)? { | |
1 => FileChangeType::Created, | |
2 => FileChangeType::Changed, | |
3 => FileChangeType::Deleted, | |
i => { | |
return Err(D::Error::invalid_value( | |
de::Unexpected::Unsigned(u64::from(i)), | |
&"value of 1, 2 or 3", | |
)) | |
} | |
}) | |
} | |
} | |
impl serde::Serialize for FileChangeType { | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
serializer.serialize_u8(*self as u8) | |
} | |
} | |
/// An event describing a file change. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct FileEvent { | |
/// The file's URI. | |
pub uri: Url, | |
/// The change type. | |
#[serde(rename = "type")] | |
pub typ: FileChangeType, | |
} | |
impl FileEvent { | |
pub fn new(uri: Url, typ: FileChangeType) -> FileEvent { | |
FileEvent { uri, typ } | |
} | |
} | |
/// Describe options to be used when registered for text document change events. | |
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)] | |
pub struct DidChangeWatchedFilesRegistrationOptions { | |
/// The watchers to register. | |
pub watchers: Vec<FileSystemWatcher>, | |
} | |
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct FileSystemWatcher { | |
/// The glob pattern to watch | |
pub glob_pattern: String, | |
/// The kind of events of interest. If omitted it defaults to WatchKind.Create | | |
/// WatchKind.Change | WatchKind.Delete which is 7. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub kind: Option<WatchKind>, | |
} | |
bitflags! { | |
pub struct WatchKind: u8 { | |
/// Interested in create events. | |
const Create = 1; | |
/// Interested in change events | |
const Change = 2; | |
/// Interested in delete events | |
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 { | |
/// The URI for which diagnostic information is reported. | |
pub uri: Url, | |
/// An array of diagnostic information items. | |
pub diagnostics: Vec<Diagnostic>, | |
} | |
impl PublishDiagnosticsParams { | |
pub fn new(uri: Url, diagnostics: Vec<Diagnostic>) -> PublishDiagnosticsParams { | |
PublishDiagnosticsParams { | |
uri, | |
diagnostics, | |
} | |
} | |
} | |
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] | |
#[serde(untagged)] | |
pub enum CompletionResponse { | |
Array(Vec<CompletionItem>), | |
List(CompletionList), | |
} | |
impl From<Vec<CompletionItem>> for CompletionResponse { | |
fn from(items: Vec<CompletionItem>) -> Self { | |
CompletionResponse::Array(items) | |
} | |
} | |
impl From<CompletionList> for CompletionResponse { | |
fn from(list: CompletionList) -> Self { | |
CompletionResponse::List(list) | |
} | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionParams { | |
// This field was "mixed-in" from TextDocumentPositionParams | |
#[serde(flatten)] | |
pub text_document_position: TextDocumentPositionParams, | |
// CompletionParams properties: | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub context: Option<CompletionContext>, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionContext { | |
/** | |
* How the completion was triggered. | |
*/ | |
pub trigger_kind: CompletionTriggerKind, | |
/** | |
* The trigger character (a single character) that has trigger code complete. | |
* Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub trigger_character: Option<String>, | |
} | |
/// How a completion was triggered. | |
#[derive(Debug, PartialEq, Clone, Copy, Deserialize_repr, Serialize_repr)] | |
#[repr(u8)] | |
pub enum CompletionTriggerKind { | |
Invoked = 1, | |
TriggerCharacter = 2, | |
TriggerForIncompleteCompletions = 3, | |
} | |
/// Represents a collection of [completion items](#CompletionItem) to be presented | |
/// in the editor. | |
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionList { | |
/// This list it not complete. Further typing should result in recomputing | |
/// this list. | |
pub is_incomplete: bool, | |
/// The completion items. | |
pub items: Vec<CompletionItem>, | |
} | |
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)] | |
#[serde(untagged)] | |
pub enum Documentation { | |
String(String), | |
MarkupContent(MarkupContent), | |
} | |
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CompletionItem { | |
/// The label of this completion item. By default | |
/// also the text that is inserted when selecting | |
/// this completion. | |
pub label: String, | |
/// The kind of this completion item. Based of the kind | |
/// an icon is chosen by the editor. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub kind: Option<CompletionItemKind>, | |
/// A human-readable string with additional information | |
/// about this item, like type or symbol information. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub detail: Option<String>, | |
/// A human-readable string that represents a doc-comment. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub documentation: Option<Documentation>, | |
/// Indicates if this item is deprecated. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub deprecated: Option<bool>, | |
/// Select this item when showing. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub preselect: Option<bool>, | |
/// A string that shoud be used when comparing this item | |
/// with other items. When `falsy` the label is used. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub sort_text: Option<String>, | |
/// A string that should be used when filtering a set of | |
/// completion items. When `falsy` the label is used. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub filter_text: Option<String>, | |
/// A string that should be inserted a document when selecting | |
/// this completion. When `falsy` the label is used. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub insert_text: Option<String>, | |
/// The format of the insert text. The format applies to both the `insertText` property | |
/// and the `newText` property of a provided `textEdit`. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub insert_text_format: Option<InsertTextFormat>, | |
/// An edit which is applied to a document when selecting | |
/// this completion. When an edit is provided the value of | |
/// insertText is ignored. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub text_edit: Option<TextEdit>, | |
/// An optional array of additional text edits that are applied when | |
/// selecting this completion. Edits must not overlap with the main edit | |
/// nor with themselves. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub additional_text_edits: Option<Vec<TextEdit>>, | |
/// An optional command that is executed *after* inserting this completion. *Note* that | |
/// additional modifications to the current document should be described with the | |
/// additionalTextEdits-property. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub command: Option<Command>, | |
/// An data entry field that is preserved on a completion item between | |
/// a completion and a completion resolve request. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub data: Option<Value>, | |
} | |
impl CompletionItem { | |
/// Create a CompletionItem with the minimum possible info (label and detail). | |
pub fn new_simple(label: String, detail: String) -> CompletionItem { | |
CompletionItem { | |
label, | |
detail: Some(detail), | |
..Self::default() | |
} | |
} | |
} | |
/// The kind of a completion entry. | |
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize_repr, Deserialize_repr)] | |
#[repr(u8)] | |
pub enum CompletionItemKind { | |
Text = 1, | |
Method = 2, | |
Function = 3, | |
Constructor = 4, | |
Field = 5, | |
Variable = 6, | |
Class = 7, | |
Interface = 8, | |
Module = 9, | |
Property = 10, | |
Unit = 11, | |
Value = 12, | |
Enum = 13, | |
Keyword = 14, | |
Snippet = 15, | |
Color = 16, | |
File = 17, | |
Reference = 18, | |
Folder = 19, | |
EnumMember = 20, | |
Constant = 21, | |
Struct = 22, | |
Event = 23, | |
Operator = 24, | |
TypeParameter = 25, | |
} | |
/// Defines how to interpret the insert text in a completion item | |
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize_repr, Deserialize_repr)] | |
#[repr(u8)] | |
pub enum InsertTextFormat { | |
PlainText = 1, | |
Snippet = 2, | |
} | |
/// The result of a hover request. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct Hover { | |
/// The hover's content | |
pub contents: HoverContents, | |
/// An optional range is a range inside a text document | |
/// that is used to visualize a hover, e.g. by changing the background color. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub range: Option<Range>, | |
} | |
/** | |
* Hover contents could be single entry or multiple entries. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] | |
#[serde(untagged)] | |
pub enum HoverContents { | |
Scalar(MarkedString), | |
Array(Vec<MarkedString>), | |
Markup(MarkupContent), | |
} | |
/** | |
The marked string is rendered: | |
- as markdown if it is represented as a string | |
- as code block of the given langauge if it is represented as a pair of a language and a value | |
The pair of a language and a value is an equivalent to markdown: | |
```${language} | |
${value} | |
``` | |
*/ | |
#[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, | |
}) | |
} | |
} | |
/// Signature help represents the signature of something | |
/// callable. There can be multiple signature but only one | |
/// active and only one active parameter. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SignatureHelp { | |
/// One or more signatures. | |
pub signatures: Vec<SignatureInformation>, | |
/// The active signature. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub active_signature: Option<i64>, | |
/// The active parameter of the active signature. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub active_parameter: Option<i64>, | |
} | |
/// Represents the signature of something callable. A signature | |
/// can have a label, like a function-name, a doc-comment, and | |
/// a set of parameters. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct SignatureInformation { | |
/// The label of this signature. Will be shown in | |
/// the UI. | |
pub label: String, | |
/// The human-readable doc-comment of this signature. Will be shown | |
/// in the UI but can be omitted. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub documentation: Option<Documentation>, | |
/// The parameters of this signature. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub parameters: Option<Vec<ParameterInformation>>, | |
} | |
/// Represents a parameter of a callable-signature. A parameter can | |
/// have a label and a doc-comment. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ParameterInformation { | |
/// The label of this parameter information. | |
/// | |
/// Either a string or an inclusive start and exclusive end offsets within its containing | |
/// signature label. (see SignatureInformation.label). *Note*: A label of type string must be | |
/// a substring of its containing signature label. | |
pub label: ParameterLabel, | |
/// The human-readable doc-comment of this parameter. Will be shown | |
/// in the UI but can be omitted. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub documentation: Option<Documentation>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum ParameterLabel { | |
Simple(String), | |
LabelOffsets([u64; 2]), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ReferenceParams { | |
// Text Document and Position fields | |
#[serde(flatten)] | |
pub text_document_position: TextDocumentPositionParams, | |
// ReferenceParams properties: | |
pub context: ReferenceContext, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Copy, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ReferenceContext { | |
/// Include the declaration of the current symbol. | |
pub include_declaration: bool, | |
} | |
/// A document highlight is a range inside a text document which deserves | |
/// special attention. Usually a document highlight is visualized by changing | |
/// the background color of its range. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct DocumentHighlight { | |
/// The range this highlight applies to. | |
pub range: Range, | |
/// The highlight kind, default is DocumentHighlightKind.Text. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub kind: Option<DocumentHighlightKind>, | |
} | |
/// A document highlight kind. | |
#[derive(Debug, Eq, PartialEq, Copy, Clone)] | |
pub enum DocumentHighlightKind { | |
/// A textual occurrance. | |
Text = 1, | |
/// Read-access of a symbol, like reading a variable. | |
Read = 2, | |
/// Write-access of a symbol, like writing to a variable. | |
Write = 3, | |
} | |
impl<'de> serde::Deserialize<'de> for DocumentHighlightKind { | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(match u8::deserialize(deserializer)? { | |
1 => DocumentHighlightKind::Text, | |
2 => DocumentHighlightKind::Read, | |
3 => DocumentHighlightKind::Write, | |
i => { | |
return Err(D::Error::invalid_value( | |
de::Unexpected::Unsigned(u64::from(i)), | |
&"1, 2, or 3", | |
)) | |
} | |
}) | |
} | |
} | |
impl serde::Serialize for DocumentHighlightKind { | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
serializer.serialize_u8(*self as u8) | |
} | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentSymbolCapability { | |
/// This capability supports dynamic registration. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/// Specific capabilities for the `SymbolKind`. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub symbol_kind: Option<SymbolKindCapability>, | |
/// The client support hierarchical document symbols. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub hierarchical_document_symbol_support: Option<bool>, | |
} | |
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] | |
#[serde(untagged)] | |
pub enum DocumentSymbolResponse { | |
Flat(Vec<SymbolInformation>), | |
Nested(Vec<DocumentSymbol>), | |
} | |
impl From<Vec<SymbolInformation>> for DocumentSymbolResponse { | |
fn from(info: Vec<SymbolInformation>) -> Self { | |
DocumentSymbolResponse::Flat(info) | |
} | |
} | |
impl From<Vec<DocumentSymbol>> for DocumentSymbolResponse { | |
fn from(symbols: Vec<DocumentSymbol>) -> Self { | |
DocumentSymbolResponse::Nested(symbols) | |
} | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentSymbolParams { | |
/// The text document. | |
pub text_document: TextDocumentIdentifier, | |
} | |
/// Represents programming constructs like variables, classes, interfaces etc. | |
/// that appear in a document. Document symbols can be hierarchical and they have two ranges: | |
/// one that encloses its definition and one that points to its most interesting range, | |
/// e.g. the range of an identifier. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentSymbol { | |
/// The name of this symbol. | |
pub name: String, | |
/// More detail for this symbol, e.g the signature of a function. If not provided the | |
/// name is used. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub detail: Option<String>, | |
/// The kind of this symbol. | |
pub kind: SymbolKind, | |
/// Indicates if this symbol is deprecated. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub deprecated: Option<bool>, | |
/// The range enclosing this symbol not including leading/trailing whitespace but everything else | |
/// like comments. This information is typically used to determine if the the clients cursor is | |
/// inside the symbol to reveal in the symbol in the UI. | |
pub range: Range, | |
/// The range that should be selected and revealed when this symbol is being picked, e.g the name of a function. | |
/// Must be contained by the the `range`. | |
pub selection_range: Range, | |
/// Children of this symbol, e.g. properties of a class. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub children: Option<Vec<DocumentSymbol>>, | |
} | |
/// Represents information about programming constructs like variables, classes, | |
/// interfaces etc. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct SymbolInformation { | |
/// The name of this symbol. | |
pub name: String, | |
/// The kind of this symbol. | |
pub kind: SymbolKind, | |
/// Indicates if this symbol is deprecated. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub deprecated: Option<bool>, | |
/// The location of this symbol. | |
pub location: Location, | |
/// The name of the symbol containing this symbol. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub container_name: Option<String>, | |
} | |
/// A symbol kind. | |
#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize_repr, Deserialize_repr)] | |
#[repr(u8)] | |
pub enum SymbolKind { | |
File = 1, | |
Module = 2, | |
Namespace = 3, | |
Package = 4, | |
Class = 5, | |
Method = 6, | |
Property = 7, | |
Field = 8, | |
Constructor = 9, | |
Enum = 10, | |
Interface = 11, | |
Function = 12, | |
Variable = 13, | |
Constant = 14, | |
String = 15, | |
Number = 16, | |
Boolean = 17, | |
Array = 18, | |
Object = 19, | |
Key = 20, | |
Null = 21, | |
EnumMember = 22, | |
Struct = 23, | |
Event = 24, | |
Operator = 25, | |
TypeParameter = 26, | |
// Capturing all unknown enums by this lib. | |
Unknown = 255, | |
} | |
/// The parameters of a Workspace Symbol Request. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct WorkspaceSymbolParams { | |
/// A non-empty query string | |
pub query: String, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ExecuteCommandParams { | |
/** | |
* The identifier of the actual command handler. | |
*/ | |
pub command: String, | |
/** | |
* Arguments that the command should be invoked with. | |
*/ | |
#[serde(default)] | |
pub arguments: Vec<Value>, | |
} | |
/** | |
* Execute command registration options. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ExecuteCommandRegistrationOptions { | |
/** | |
* The commands to be executed on the server | |
*/ | |
pub commands: Vec<String>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ApplyWorkspaceEditParams { | |
/** | |
* The edits to apply. | |
*/ | |
pub edit: WorkspaceEdit, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct ApplyWorkspaceEditResponse { | |
/** | |
* Indicates whether the edit was applied or not. | |
*/ | |
pub applied: bool, | |
} | |
/// Params for the CodeActionRequest | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeActionParams { | |
/// The document in which the command was invoked. | |
pub text_document: TextDocumentIdentifier, | |
/// The range for which the command was invoked. | |
pub range: Range, | |
/// Context carrying additional information. | |
pub context: CodeActionContext, | |
} | |
/// response for CodeActionRequest | |
pub type CodeActionResponse = Vec<CodeActionOrCommand>; | |
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum CodeActionOrCommand { | |
Command(Command), | |
CodeAction(CodeAction), | |
} | |
impl From<Command> for CodeActionOrCommand { | |
fn from(comand: Command) -> Self { | |
CodeActionOrCommand::Command(comand) | |
} | |
} | |
impl From<CodeAction> for CodeActionOrCommand { | |
fn from(action: CodeAction) -> Self { | |
CodeActionOrCommand::CodeAction(action) | |
} | |
} | |
/** | |
* A set of predefined code action kinds | |
*/ | |
pub mod code_action_kind { | |
/** | |
* Base kind for quickfix actions: 'quickfix' | |
*/ | |
pub const QUICKFIX: &str = "quickfix"; | |
/** | |
* Base kind for refactoring actions: 'refactor' | |
*/ | |
pub const REFACTOR: &str = "refactor"; | |
/** | |
* Base kind for refactoring extraction actions: 'refactor.extract' | |
* | |
* Example extract actions: | |
* | |
* - Extract method | |
* - Extract function | |
* - Extract variable | |
* - Extract interface from class | |
* - ... | |
*/ | |
pub const REFACTOR_EXTRACT: &str = "refactor.extract"; | |
/** | |
* Base kind for refactoring inline actions: 'refactor.inline' | |
* | |
* Example inline actions: | |
* | |
* - Inline function | |
* - Inline variable | |
* - Inline constant | |
* - ... | |
*/ | |
pub const REFACTOR_INLINE: &str = "refactor.inline"; | |
/** | |
* Base kind for refactoring rewrite actions: 'refactor.rewrite' | |
* | |
* Example rewrite actions: | |
* | |
* - Convert JavaScript function to class | |
* - Add or remove parameter | |
* - Encapsulate field | |
* - Make method static | |
* - Move method to base class | |
* - ... | |
*/ | |
pub const REFACTOR_REWRITE: &str = "refactor.rewrite"; | |
/** | |
* Base kind for source actions: `source` | |
* | |
* Source code actions apply to the entire file. | |
*/ | |
pub const SOURCE: &str = "source"; | |
/** | |
* Base kind for an organize imports source action: `source.organizeImports` | |
*/ | |
pub const SOURCE_ORGANIZE_IMPORTS: &str = "source.organizeImports"; | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct CodeAction { | |
/// A short, human-readable, title for this code action. | |
pub title: String, | |
/// The kind of the code action. | |
/// Used to filter code actions. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub kind: Option<String>, | |
/// The diagnostics that this code action resolves. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub diagnostics: Option<Vec<Diagnostic>>, | |
/// The workspace edit this code action performs. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub edit: Option<WorkspaceEdit>, | |
/// A command this code action executes. If a code action | |
/// provides an edit and a command, first the edit is | |
/// executed and then the command. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub command: Option<Command>, | |
} | |
/// Contains additional diagnostic information about the context in which | |
/// a code action is run. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct CodeActionContext { | |
/// An array of diagnostics. | |
pub diagnostics: Vec<Diagnostic>, | |
/// Requested kind of actions to return. | |
/// | |
/// Actions not of this kind are filtered out by the client before being shown. So servers | |
/// can omit computing them. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub only: Option<Vec<String>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeActionOptions { | |
/** | |
* CodeActionKinds that this server may return. | |
* | |
* The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server | |
* may list out every specific kind they provide. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub code_action_kinds: Option<Vec<String>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct CodeLensParams { | |
/// The document to request code lens for. | |
pub text_document: TextDocumentIdentifier, | |
} | |
/// A code lens represents a command that should be shown along with | |
/// source text, like the number of references, a way to run tests, etc. | |
/// | |
/// A code lens is _unresolved_ when no command is associated to it. For performance | |
/// reasons the creation of a code lens and resolving should be done in two stages. | |
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] | |
pub struct CodeLens { | |
/// The range in which this code lens is valid. Should only span a single line. | |
pub range: Range, | |
/// The command this code lens represents. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub command: Option<Command>, | |
/// A data entry field that is preserved on a code lens item between | |
/// a code lens and a code lens resolve request. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub data: Option<Value>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentLinkParams { | |
/** | |
* The document to provide document links for. | |
*/ | |
pub text_document: TextDocumentIdentifier, | |
} | |
/** | |
* A document link is a range in a text document that links to an internal or external resource, like another | |
* text document or a web site. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct DocumentLink { | |
/** | |
* The range this link applies to. | |
*/ | |
pub range: Range, | |
/** | |
* The uri this link points to. | |
*/ | |
pub target: Url, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentFormattingParams { | |
/// The document to format. | |
pub text_document: TextDocumentIdentifier, | |
/// The format options. | |
pub options: FormattingOptions, | |
} | |
/// Value-object describing what options formatting should use. | |
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct FormattingOptions { | |
/// Size of a tab in spaces. | |
pub tab_size: u64, | |
/// Prefer spaces over tabs. | |
pub insert_spaces: bool, | |
/// Signature for further properties. | |
#[serde(flatten)] | |
pub properties: HashMap<String, FormattingProperty>, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum FormattingProperty { | |
Bool(bool), | |
Number(f64), | |
String(String), | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentRangeFormattingParams { | |
/// The document to format. | |
pub text_document: TextDocumentIdentifier, | |
/// The range to format | |
pub range: Range, | |
/// The format options | |
pub options: FormattingOptions, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentOnTypeFormattingParams { | |
/// Text Document and Position fields. | |
#[serde(flatten)] | |
pub text_document_position: TextDocumentPositionParams, | |
/// The character that has been typed. | |
pub ch: String, | |
/// The format options. | |
pub options: FormattingOptions, | |
} | |
/// Extends TextDocumentRegistrationOptions | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentOnTypeFormattingRegistrationOptions { | |
/** | |
* A document selector to identify the scope of the registration. If set to null | |
* the document selector provided on the client side will be used. | |
*/ | |
pub document_selector: Option<DocumentSelector>, | |
/** | |
* A character on which formatting should be triggered, like `}`. | |
*/ | |
pub first_trigger_character: String, | |
/** | |
* More trigger characters. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub more_trigger_character: Option<Vec<String>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct RenameParams { | |
/// Text Document and Position fields | |
#[serde(flatten)] | |
pub text_document_position: TextDocumentPositionParams, | |
/// The new name of the symbol. If the given name is not valid the | |
/// request must return a [ResponseError](#ResponseError) with an | |
/// appropriate message set. | |
pub new_name: String, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum RenameProviderCapability { | |
Simple(bool), | |
Options(RenameOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct RenameOptions { | |
/// Renames should be checked and tested before being executed. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub prepare_provider: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct RenameCapability { | |
/// Whether rename supports dynamic registration. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/// Client supports testing for validity of rename operations before execution. | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub prepare_support: Option<bool>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum PrepareRenameResponse { | |
Range(Range), | |
RangeWithPlaceholder { range: Range, placeholder: String }, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct DocumentColorParams { | |
/// The text document | |
pub text_document: TextDocumentIdentifier, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ColorInformation { | |
/** | |
* The range in the document where this color appears. | |
*/ | |
pub range: Range, | |
/** | |
* The actual color value for this color range. | |
*/ | |
pub color: Color, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct Color { | |
/** | |
* The red component of this color in the range [0-1]. | |
*/ | |
pub red: f64, | |
/** | |
* The green component of this color in the range [0-1]. | |
*/ | |
pub green: f64, | |
/** | |
* The blue component of this color in the range [0-1]. | |
*/ | |
pub blue: f64, | |
/** | |
* The alpha component of this color in the range [0-1]. | |
*/ | |
pub alpha: f64, | |
} | |
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ColorPresentationParams { | |
/** | |
* The text document. | |
*/ | |
pub text_document: TextDocumentIdentifier, | |
/** | |
* The color information to request presentations for. | |
*/ | |
pub color: Color, | |
/** | |
* The range where the color would be inserted. Serves as a context. | |
*/ | |
pub range: Range, | |
} | |
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Default, Clone)] | |
#[serde(rename_all = "camelCase")] | |
pub struct ColorPresentation { | |
/** | |
* The label of this color presentation. It will be shown on the color | |
* picker header. By default this is also the text that is inserted when selecting | |
* this color presentation. | |
*/ | |
pub label: String, | |
/** | |
* An [edit](#TextEdit) which is applied to a document when selecting | |
* this presentation for the color. When `falsy` the [label](#ColorPresentation.label) | |
* is used. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub text_edit: Option<TextEdit>, | |
/** | |
* An optional array of additional [text edits](#TextEdit) that are applied when | |
* selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub additional_text_edits: Option<Vec<TextEdit>>, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct FoldingRangeParams { | |
/// The text document. | |
pub text_document: TextDocumentIdentifier, | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(untagged)] | |
pub enum FoldingRangeProviderCapability { | |
Simple(bool), | |
FoldingProvider(FoldingProviderOptions), | |
Options(StaticTextDocumentColorProviderOptions), | |
} | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
pub struct FoldingProviderOptions {} | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct FoldingRangeCapability { | |
/** | |
* Whether implementation supports dynamic registration for folding range providers. If this is set to `true` | |
* the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)` | |
* return value for the corresponding server capability as well. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub dynamic_registration: Option<bool>, | |
/** | |
* The maximum number of folding ranges that the client prefers to receive per document. The value serves as a | |
* hint, servers are free to follow the limit. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub range_limit: Option<u64>, | |
/** | |
* If set, the client signals that it only supports folding complete lines. If set, client will | |
* ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub line_folding_only: Option<bool>, | |
} | |
/** | |
* Represents a folding range. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
pub struct FoldingRange { | |
/** | |
* The zero-based line number from where the folded range starts. | |
*/ | |
pub start_line: u64, | |
/** | |
* The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub start_character: Option<u64>, | |
/** | |
* The zero-based line number where the folded range ends. | |
*/ | |
pub end_line: u64, | |
/** | |
* The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub end_character: Option<u64>, | |
/** | |
* Describes the kind of the folding range such as `comment' or 'region'. The kind | |
* is used to categorize folding ranges and used by commands like 'Fold all comments'. See | |
* [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds. | |
*/ | |
#[serde(skip_serializing_if = "Option::is_none")] | |
pub kind: Option<FoldingRangeKind>, | |
} | |
/// A parameter literal used in selection range requests. | |
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
#[cfg(feature = "proposed")] | |
pub struct SelectionRangeParams { | |
/// The text document. | |
pub text_document: TextDocumentIdentifier, | |
/// The positions inside the text document. | |
pub positions: Vec<Position>, | |
} | |
/// Represents a selection range. | |
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | |
#[serde(rename_all = "camelCase")] | |
#[cfg(feature = "proposed")] | |
pub struct SelectionRange { | |
/// Range of the selection. | |
pub range: Range, | |
/// The parent selection range containing this range. | |
pub parent: Option<Box<SelectionRange>>, | |
} | |
/** | |
* Enum of known range kinds | |
*/ | |
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)] | |
#[serde(rename_all = "lowercase")] | |
pub enum FoldingRangeKind { | |
/// Folding range for a comment | |
Comment, | |
/// Folding range for a imports or includes | |
Imports, | |
/// Folding range for a region (e.g. `#region`) | |
Region, | |
} | |
/** | |
* Describes the content type that a client supports in various | |
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`. | |
* | |
* Please note that `MarkupKinds` must not start with a `$`. This kinds | |
* are reserved for internal usage. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)] | |
#[serde(rename_all = "lowercase")] | |
pub enum MarkupKind { | |
/// Plain text is supported as a content format | |
PlainText, | |
/// Markdown is supported as a content format | |
Markdown, | |
} | |
/** | |
* A `MarkupContent` literal represents a string value which content is interpreted base on its | |
* kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds. | |
* | |
* If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues. | |
* See <https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting> | |
* | |
* Here is an example how such a string can be constructed using JavaScript / TypeScript: | |
* ```ts | |
* let markdown: MarkdownContent = { | |
* kind: MarkupKind.Markdown, | |
* value: [ | |
* '# Header', | |
* 'Some text', | |
* '```typescript', | |
* 'someCode();', | |
* '```' | |
* ].join('\n') | |
* }; | |
* ``` | |
* | |
* *Please Note* that clients might sanitize the return markdown. A client could decide to | |
* remove HTML from the markdown to avoid script execution. | |
*/ | |
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)] | |
pub struct MarkupContent { | |
pub kind: MarkupKind, | |
pub value: String, | |
} | |
#[cfg(feature = "proposed")] | |
/// The progress notification is sent from the server to the client to ask | |
/// the client to indicate progress. | |
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)] | |
pub struct ProgressParams { | |
/// A unique identifier to associate multiple progress notifications | |
/// with the same progress. | |
pub id: String, | |
/// Mandatory title of the progress operation. Used to briefly inform | |
/// about the kind of operation being performed. | |
/// Examples: "Indexing" or "Linking dependencies". | |
pub title: String, | |
/// Optional, more detailed associated progress message. Contains | |
/// complementary information to the `title`. | |
/// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". | |
/// If unset, the previous progress message (if any) is still valid. | |
pub message: Option<String>, | |
/// Optional progress percentage to display (value 100 is considered 100%). | |
/// If unset, the previous progress percentage (if any) is still valid. | |
pub percentage: Option<f64>, | |
/// Set to true on the final progress update. | |
/// No more progress notifications with the same ID should be sent. | |
pub done: Option<bool>, | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
use serde::{Deserialize, Serialize}; | |
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); | |
} | |
#[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, | |
}, | |
r#"{"changes":{}}"#, | |
); | |
test_serialization( | |
&WorkspaceEdit { | |
changes: None, | |
document_changes: None, | |
}, | |
r#"{}"#, | |
); | |
test_serialization( | |
&WorkspaceEdit { | |
changes: Some( | |
vec![(Url::parse("file://test").unwrap(), vec![])] | |
.into_iter() | |
.collect(), | |
), | |
document_changes: None, | |
}, | |
r#"{"changes":{"file://test/":[]}}"#, | |
); | |
} | |
#[test] | |
fn formatting_options() { | |
test_serialization( | |
&FormattingOptions { | |
tab_size: 123, | |
insert_spaces: true, | |
properties: HashMap::new(), | |
}, | |
r#"{"tabSize":123,"insertSpaces":true}"#, | |
); | |
test_serialization( | |
&FormattingOptions { | |
tab_size: 123, | |
insert_spaces: true, | |
properties: vec![("prop".to_string(), FormattingProperty::Number(1.0))] | |
.into_iter() | |
.collect(), | |
}, | |
r#"{"tabSize":123,"insertSpaces":true,"prop":1.0}"#, | |
); | |
} | |
#[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"]"#, | |
); | |
} | |
#[test] | |
fn test_code_action_response() { | |
test_serialization( | |
&vec![ | |
CodeActionOrCommand::Command(Command { | |
title: "title".to_string(), | |
command: "command".to_string(), | |
arguments: None, | |
}), | |
CodeActionOrCommand::CodeAction(CodeAction { | |
title: "title".to_string(), | |
kind: Some(code_action_kind::QUICKFIX.to_owned()), | |
command: None, | |
diagnostics: None, | |
edit: None, | |
}), | |
], | |
r#"[{"title":"title","command":"command"},{"title":"title","kind":"quickfix"}]"#, | |
) | |
} | |
} |