use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::{
Command, Documentation, MarkupKind, PartialResultParams, TagSupport,
TextDocumentPositionParams, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,
WorkDoneProgressParams,
};
use crate::Range;
use serde_json::Value;
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum InsertTextFormat {
PlainText = 1,
Snippet = 2,
}
#[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,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemCapability {
#[serde(skip_serializing_if = "Option::is_none")]
pub snippet_support: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub commit_characters_support: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation_format: Option<Vec<MarkupKind>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deprecated_support: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preselect_support: Option<bool>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "TagSupport::deserialize_compat"
)]
pub tag_support: Option<TagSupport<CompletionItemTag>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_replace_support: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resolve_support: Option<CompletionItemCapabilityResolveSupport>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text_mode_support: Option<InsertTextModeSupport>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemCapabilityResolveSupport {
pub properties: Vec<String>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InsertTextModeSupport {
pub value_set: Vec<InsertTextMode>,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum InsertTextMode {
AsIs = 1,
AdjustIndentation = 2,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum CompletionItemTag {
Deprecated = 1,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemKindCapability {
#[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 CompletionClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub dynamic_registration: Option<bool>,
#[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>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context_support: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InsertReplaceEdit {
pub new_text: String,
pub insert: Range,
pub replace: Range,
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum CompletionTextEdit {
Edit(TextEdit),
InsertAndReplace(InsertReplaceEdit),
}
impl From<TextEdit> for CompletionTextEdit {
fn from(edit: TextEdit) -> Self {
CompletionTextEdit::Edit(edit)
}
}
impl From<InsertReplaceEdit> for CompletionTextEdit {
fn from(edit: InsertReplaceEdit) -> Self {
CompletionTextEdit::InsertAndReplace(edit)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub resolve_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_characters: Option<Vec<String>>,
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct CompletionRegistrationOptions {
#[serde(flatten)]
pub text_document_registration_options: TextDocumentRegistrationOptions,
#[serde(flatten)]
pub completion_options: CompletionOptions,
}
#[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 {
#[serde(flatten)]
pub text_document_position: TextDocumentPositionParams,
#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
#[serde(flatten)]
pub partial_result_params: PartialResultParams,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<CompletionContext>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionContext {
pub trigger_kind: CompletionTriggerKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_character: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Copy, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum CompletionTriggerKind {
Invoked = 1,
TriggerCharacter = 2,
TriggerForIncompleteCompletions = 3,
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionList {
pub is_incomplete: bool,
pub items: Vec<CompletionItem>,
}
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItem {
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<CompletionItemKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option<Documentation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deprecated: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preselect: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text_format: Option<InsertTextFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text_mode: Option<InsertTextMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_edit: Option<CompletionTextEdit>,
#[serde(skip_serializing_if = "Option::is_none")]
pub additional_text_edits: Option<Vec<TextEdit>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<Command>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<CompletionItemTag>>,
}
impl CompletionItem {
pub fn new_simple(label: String, detail: String) -> CompletionItem {
CompletionItem {
label,
detail: Some(detail),
..Self::default()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::test_deserialization;
#[test]
fn test_tag_support_deserialization() {
let mut empty = CompletionItemCapability::default();
empty.tag_support = None;
test_deserialization(r#"{}"#, &empty);
test_deserialization(r#"{"tagSupport": false}"#, &empty);
let mut t = CompletionItemCapability::default();
t.tag_support = Some(TagSupport { value_set: vec![] });
test_deserialization(r#"{"tagSupport": true}"#, &t);
let mut t = CompletionItemCapability::default();
t.tag_support = Some(TagSupport {
value_set: vec![CompletionItemTag::Deprecated],
});
test_deserialization(r#"{"tagSupport": {"valueSet": [1]}}"#, &t);
}
}