use serde::Deserialize;
use serde_repr::Deserialize_repr;
mod completion;
mod semantic_tokens;
pub use completion::CompletionClientCapabilities;
pub use semantic_tokens::SemanticTokensClientCapabilities;
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ClientCapabilities {
pub workspace: Option<WorkspaceCapabilities>,
pub text_document: Option<TextDocumentClientCapabilities>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceCapabilities {
pub apply_edit: Option<bool>,
pub workspace_edit: Option<WorkspaceEditClientCapabilities>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceEditClientCapabilities {
pub document_changes: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentClientCapabilities {
pub synchronization: Option<TextDocumentSyncClientCapabilities>,
pub completion: Option<CompletionClientCapabilities>,
pub hover: Option<HoverClientCapabilities>,
pub signature_help: Option<SignatureHelpClientCapabilities>,
pub declaration: Option<DeclarationClientCapabilities>,
pub definition: Option<DefinitionClientCapabilities>,
pub type_definition: Option<TypeDefinitionClientCapabilities>,
pub implementation: Option<ImplementationClientCapabilities>,
pub references: Option<ReferenceClientCapabilities>,
pub document_highlight: Option<DocumentHighlightClientCapabilities>,
pub document_symbol: Option<DocumentSymbolClientCapabilities>,
pub code_action: Option<CodeActionClientCapabilities>,
pub code_lens: Option<CodeLensClientCapabilities>,
pub document_link: Option<DocumentLinkClientCapabilities>,
pub color_provider: Option<DocumentColorClientCapabilities>,
pub formatting: Option<DocumentFormattingClientCapabilities>,
pub range_formatting: Option<DocumentRangeFormattingClientCapabilities>,
pub on_type_formatting: Option<DocumentOnTypeFormattingClientCapabilities>,
pub rename: Option<RenameClientCapabilities>,
pub publish_diagnostics: Option<PublishDiagnosticsClientCapabilities>,
pub folding_range: Option<FoldingRangeClientCapabilities>,
pub selection_range: Option<SelectionRangeClientCapabilities>,
pub linked_editing_range: Option<LinkedEditingRangeClientCapabilities>,
pub call_hierarchy: Option<CallHierarchyClientCapabilities>,
pub semantic_tokens: Option<SemanticTokensClientCapabilities>,
pub moniker: Option<MonikerClientCapabilities>,
pub type_hierarchy: Option<TypeHierarchyClientCapabilities>,
pub inline_value: Option<InlineValueClientCapabilities>,
pub inlay_hint: Option<InlayHintClientCapabilities>,
pub diagnostic: Option<DiagnosticClientCapabilities>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum MarkupKind {
Plaintext,
Markdown,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ValueSet<T> {
pub value_set: Vec<T>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ResolveSupport {
pub properties: Vec<String>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentSyncClientCapabilities {
pub dynamic_registration: Option<bool>,
pub will_save: Option<bool>,
pub will_save_wait_until: Option<bool>,
pub did_save: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HoverClientCapabilities {
pub dynamic_registration: Option<bool>,
pub content_format: Option<Vec<MarkupKind>>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DeclarationClientCapabilities {
pub dynamic_registration: Option<bool>,
pub link_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DefinitionClientCapabilities {
pub dynamic_registration: Option<bool>,
pub link_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TypeDefinitionClientCapabilities {
pub dynamic_registration: Option<bool>,
pub link_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ImplementationClientCapabilities {
pub dynamic_registration: Option<bool>,
pub link_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ReferenceClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentHighlightClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CodeLensClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentLinkClientCapabilities {
pub dynamic_registration: Option<bool>,
pub tooltip_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentColorClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentFormattingClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentRangeFormattingClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentOnTypeFormattingClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SelectionRangeClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct LinkedEditingRangeClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MonikerClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TypeHierarchyClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InlineValueClientCapabilities {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SignatureHelpClientCapabilities {
pub dynamic_registration: Option<bool>,
pub signature_information: Option<SignatureHelpSignatureInformation>,
pub context_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SignatureHelpSignatureInformation {
pub documentation_format: Option<Vec<MarkupKind>>,
pub parameter_information: Option<SignatureHelpParameterInformation>,
pub active_parameter_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SignatureHelpParameterInformation {
pub label_offset_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentSymbolClientCapabilities {
pub dynamic_registration: Option<bool>,
pub symbol_kind: Option<DocumentSymbolKindCapabilities>,
pub hierarchical_document_symbol_support: Option<bool>,
pub tag_support: Option<ValueSet<SymbolTag>>,
pub label_support: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DocumentSymbolKindCapabilities {
pub value_set: Option<Vec<SymbolKind>>,
}
#[derive(Debug, Deserialize_repr, PartialEq, Clone)]
#[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,
}
#[derive(Debug, Deserialize_repr, PartialEq, Clone)]
#[repr(u8)]
pub enum SymbolTag {
Deprecated = 1,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CodeActionClientCapabilities {
pub dynamic_registration: Option<bool>,
pub code_action_literal_support: Option<CodeActionLiteralSupport>,
pub is_preferred_support: Option<bool>,
pub disabled_support: Option<bool>,
pub data_support: Option<bool>,
pub resolve_support: Option<ResolveSupport>,
pub honors_change_annotations: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CodeActionLiteralSupport {
pub code_action_kind: CodeActionKindCapabilities,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CodeActionKindCapabilities {
pub value_set: Vec<String>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct RenameClientCapabilities {
pub dynamic_registration: Option<bool>,
pub prepare_support: Option<bool>,
pub prepare_support_default_behavior: Option<PrepareSupportDefaultBehavior>,
pub honors_change_annotations: Option<bool>,
}
#[derive(Debug, Deserialize_repr, PartialEq, Clone)]
#[repr(u8)]
pub enum PrepareSupportDefaultBehavior {
Identifier = 1,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PublishDiagnosticsClientCapabilities {
pub related_information: Option<bool>,
pub tag_support: Option<ValueSet<DiagnosticTag>>,
pub version_support: Option<bool>,
pub code_description_support: Option<bool>,
pub data_support: Option<bool>,
}
#[derive(Debug, Deserialize_repr, PartialEq, Clone)]
#[repr(u8)]
pub enum DiagnosticTag {
Unnecessary = 1,
Deprecated = 2,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FoldingRangeClientCapabilities {
pub dynamic_registration: Option<bool>,
pub range_limit: Option<u32>,
pub line_folding_only: Option<bool>,
pub folding_range_kind: Option<FoldingRangeKindCapabilities>,
pub folding_range: Option<FoldingRangeCapabilities>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FoldingRangeKindCapabilities {
pub value_set: Option<Vec<FoldingRangeKind>>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum FoldingRangeKind {
Comment,
Imports,
Region,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FoldingRangeCapabilities {
pub collapsed_text: Option<bool>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintClientCapabilities {
pub dynamic_registration: Option<bool>,
pub resolve_support: Option<ResolveSupport>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticClientCapabilities {
pub dynamic_registration: Option<bool>,
pub related_document_support: Option<bool>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize_text_document_client_capabilities() {
let json = r#"{
"synchronization": {
"dynamicRegistration": true,
"willSave": true,
"willSaveWaitUntil": true,
"didSave": true
},
"completion": {
"dynamicRegistration": true,
"completionItem": {
"snippetSupport": true,
"commitCharactersSupport": true,
"documentationFormat": ["markdown", "plaintext"],
"deprecatedSupport": true,
"preselectSupport": true,
"insertReplaceSupport": true,
"labelDetailsSupport": true
},
"completionItemKind": {
"valueSet": [1, 2, 3, 4, 5, 6]
},
"contextSupport": true
},
"hover": {
"dynamicRegistration": true,
"contentFormat": ["markdown", "plaintext"]
},
"signatureHelp": {
"dynamicRegistration": true,
"signatureInformation": {
"documentationFormat": ["markdown"],
"parameterInformation": {
"labelOffsetSupport": true
},
"activeParameterSupport": true
},
"contextSupport": true
},
"definition": {
"dynamicRegistration": true,
"linkSupport": true
},
"documentSymbol": {
"dynamicRegistration": true,
"symbolKind": {
"valueSet": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
},
"hierarchicalDocumentSymbolSupport": true,
"labelSupport": true
},
"codeAction": {
"dynamicRegistration": true,
"codeActionLiteralSupport": {
"codeActionKind": {
"valueSet": ["quickfix", "refactor", "source"]
}
},
"isPreferredSupport": true,
"dataSupport": true,
"resolveSupport": {
"properties": ["edit"]
}
},
"formatting": {
"dynamicRegistration": true
},
"publishDiagnostics": {
"relatedInformation": true,
"tagSupport": {
"valueSet": [1, 2]
},
"versionSupport": true,
"codeDescriptionSupport": true,
"dataSupport": true
},
"foldingRange": {
"dynamicRegistration": true,
"rangeLimit": 5000,
"lineFoldingOnly": true,
"foldingRangeKind": {
"valueSet": ["comment", "imports", "region"]
},
"foldingRange": {
"collapsedText": true
}
},
"rename": {
"dynamicRegistration": true,
"prepareSupport": true,
"prepareSupportDefaultBehavior": 1,
"honorsChangeAnnotations": true
},
"diagnostic": {
"dynamicRegistration": true,
"relatedDocumentSupport": true
}
}"#;
let caps: TextDocumentClientCapabilities = serde_json::from_str(json).unwrap();
let sync = caps.synchronization.unwrap();
assert_eq!(sync.dynamic_registration, Some(true));
assert_eq!(sync.will_save, Some(true));
assert_eq!(sync.will_save_wait_until, Some(true));
assert_eq!(sync.did_save, Some(true));
let completion = caps.completion.unwrap();
assert_eq!(completion.dynamic_registration, Some(true));
assert_eq!(completion.context_support, Some(true));
let item = completion.completion_item.unwrap();
assert_eq!(item.snippet_support, Some(true));
assert_eq!(
item.documentation_format,
Some(vec![MarkupKind::Markdown, MarkupKind::Plaintext])
);
assert_eq!(item.label_details_support, Some(true));
let item_kind = completion.completion_item_kind.unwrap();
assert_eq!(item_kind.value_set.unwrap().len(), 6);
let hover = caps.hover.unwrap();
assert_eq!(hover.dynamic_registration, Some(true));
assert_eq!(
hover.content_format,
Some(vec![MarkupKind::Markdown, MarkupKind::Plaintext])
);
let sig = caps.signature_help.unwrap();
assert_eq!(sig.context_support, Some(true));
let sig_info = sig.signature_information.unwrap();
assert_eq!(sig_info.active_parameter_support, Some(true));
assert_eq!(
sig_info.parameter_information.unwrap().label_offset_support,
Some(true)
);
let def = caps.definition.unwrap();
assert_eq!(def.link_support, Some(true));
let doc_sym = caps.document_symbol.unwrap();
assert_eq!(doc_sym.hierarchical_document_symbol_support, Some(true));
assert_eq!(doc_sym.symbol_kind.unwrap().value_set.unwrap().len(), 13);
let code_action = caps.code_action.unwrap();
assert_eq!(code_action.is_preferred_support, Some(true));
assert_eq!(code_action.data_support, Some(true));
assert_eq!(
code_action.resolve_support.unwrap().properties,
vec!["edit".to_string()]
);
assert_eq!(
code_action
.code_action_literal_support
.unwrap()
.code_action_kind
.value_set,
vec![
"quickfix".to_string(),
"refactor".to_string(),
"source".to_string()
]
);
let formatting = caps.formatting.unwrap();
assert_eq!(formatting.dynamic_registration, Some(true));
let pub_diag = caps.publish_diagnostics.unwrap();
assert_eq!(pub_diag.related_information, Some(true));
assert_eq!(pub_diag.version_support, Some(true));
assert_eq!(pub_diag.code_description_support, Some(true));
assert_eq!(
pub_diag.tag_support.unwrap().value_set,
vec![DiagnosticTag::Unnecessary, DiagnosticTag::Deprecated]
);
let folding = caps.folding_range.unwrap();
assert_eq!(folding.range_limit, Some(5000));
assert_eq!(folding.line_folding_only, Some(true));
assert_eq!(
folding.folding_range_kind.unwrap().value_set,
Some(vec![
FoldingRangeKind::Comment,
FoldingRangeKind::Imports,
FoldingRangeKind::Region,
])
);
assert_eq!(folding.folding_range.unwrap().collapsed_text, Some(true));
let rename = caps.rename.unwrap();
assert_eq!(rename.prepare_support, Some(true));
assert_eq!(
rename.prepare_support_default_behavior,
Some(PrepareSupportDefaultBehavior::Identifier)
);
assert_eq!(rename.honors_change_annotations, Some(true));
let diagnostic = caps.diagnostic.unwrap();
assert_eq!(diagnostic.related_document_support, Some(true));
assert!(caps.declaration.is_none());
assert!(caps.type_definition.is_none());
assert!(caps.implementation.is_none());
assert!(caps.references.is_none());
assert!(caps.document_highlight.is_none());
assert!(caps.code_lens.is_none());
assert!(caps.document_link.is_none());
assert!(caps.color_provider.is_none());
assert!(caps.range_formatting.is_none());
assert!(caps.on_type_formatting.is_none());
assert!(caps.selection_range.is_none());
assert!(caps.linked_editing_range.is_none());
assert!(caps.call_hierarchy.is_none());
assert!(caps.semantic_tokens.is_none());
assert!(caps.moniker.is_none());
assert!(caps.type_hierarchy.is_none());
assert!(caps.inline_value.is_none());
assert!(caps.inlay_hint.is_none());
}
}