1use lsp_types::{ClientCapabilities, MarkupKind};
2
3pub trait ClientCapabilitiesExt {
4 fn has_definition_link_support(&self) -> bool;
5
6 fn has_hierarchical_document_symbol_support(&self) -> bool;
7
8 fn has_work_done_progress_support(&self) -> bool;
9
10 fn has_hover_markdown_support(&self) -> bool;
11
12 fn has_pull_configuration_support(&self) -> bool;
13
14 fn has_push_configuration_support(&self) -> bool;
15
16 fn has_file_watching_support(&self) -> bool;
17}
18
19impl ClientCapabilitiesExt for ClientCapabilities {
20 fn has_definition_link_support(&self) -> bool {
21 self.text_document
22 .as_ref()
23 .and_then(|cap| cap.definition.as_ref())
24 .and_then(|cap| cap.link_support)
25 == Some(true)
26 }
27
28 fn has_hierarchical_document_symbol_support(&self) -> bool {
29 self.text_document
30 .as_ref()
31 .and_then(|cap| cap.document_symbol.as_ref())
32 .and_then(|cap| cap.hierarchical_document_symbol_support)
33 == Some(true)
34 }
35
36 fn has_work_done_progress_support(&self) -> bool {
37 self.window.as_ref().and_then(|cap| cap.work_done_progress) == Some(true)
38 }
39
40 fn has_hover_markdown_support(&self) -> bool {
41 self.text_document
42 .as_ref()
43 .and_then(|cap| cap.hover.as_ref())
44 .and_then(|cap| cap.content_format.as_ref())
45 .filter(|formats| formats.contains(&MarkupKind::Markdown))
46 .is_some()
47 }
48
49 fn has_pull_configuration_support(&self) -> bool {
50 self.workspace.as_ref().and_then(|cap| cap.configuration) == Some(true)
51 }
52
53 fn has_push_configuration_support(&self) -> bool {
54 self.workspace
55 .as_ref()
56 .and_then(|cap| cap.did_change_configuration)
57 .and_then(|cap| cap.dynamic_registration)
58 == Some(true)
59 }
60
61 fn has_file_watching_support(&self) -> bool {
62 self.workspace
63 .as_ref()
64 .and_then(|cap| cap.did_change_watched_files)
65 .and_then(|cap| cap.dynamic_registration)
66 == Some(true)
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use lsp_types::{
74 DocumentSymbolClientCapabilities, GotoCapability, HoverClientCapabilities,
75 TextDocumentClientCapabilities, WindowClientCapabilities,
76 };
77
78 #[test]
79 fn test_has_definition_link_support_true() {
80 let capabilities = ClientCapabilities {
81 text_document: Some(TextDocumentClientCapabilities {
82 definition: Some(GotoCapability {
83 link_support: Some(true),
84 ..GotoCapability::default()
85 }),
86 ..TextDocumentClientCapabilities::default()
87 }),
88 ..ClientCapabilities::default()
89 };
90 assert!(capabilities.has_definition_link_support());
91 }
92
93 #[test]
94 fn test_has_definition_link_support_false() {
95 let capabilities = ClientCapabilities::default();
96 assert!(!capabilities.has_definition_link_support());
97 }
98
99 #[test]
100 fn test_has_hierarchical_document_symbol_support_true() {
101 let capabilities = ClientCapabilities {
102 text_document: Some(TextDocumentClientCapabilities {
103 document_symbol: Some(DocumentSymbolClientCapabilities {
104 hierarchical_document_symbol_support: Some(true),
105 ..DocumentSymbolClientCapabilities::default()
106 }),
107 ..TextDocumentClientCapabilities::default()
108 }),
109 ..ClientCapabilities::default()
110 };
111 assert!(capabilities.has_hierarchical_document_symbol_support());
112 }
113
114 #[test]
115 fn test_has_hierarchical_document_symbol_support_false() {
116 let capabilities = ClientCapabilities::default();
117 assert!(!capabilities.has_hierarchical_document_symbol_support());
118 }
119
120 #[test]
121 fn test_has_work_done_progress_support_true() {
122 let capabilities = ClientCapabilities {
123 window: Some(WindowClientCapabilities {
124 work_done_progress: Some(true),
125 ..WindowClientCapabilities::default()
126 }),
127 ..ClientCapabilities::default()
128 };
129 assert!(capabilities.has_work_done_progress_support());
130 }
131
132 #[test]
133 fn test_has_work_done_progress_support_false() {
134 let capabilities = ClientCapabilities::default();
135 assert!(!capabilities.has_work_done_progress_support());
136 }
137
138 #[test]
139 fn test_has_hover_markdown_support_true() {
140 let capabilities = ClientCapabilities {
141 text_document: Some(TextDocumentClientCapabilities {
142 hover: Some(HoverClientCapabilities {
143 content_format: Some(vec![MarkupKind::PlainText, MarkupKind::Markdown]),
144 ..HoverClientCapabilities::default()
145 }),
146 ..TextDocumentClientCapabilities::default()
147 }),
148 ..ClientCapabilities::default()
149 };
150 assert!(capabilities.has_hover_markdown_support());
151 }
152
153 #[test]
154 fn test_has_hover_markdown_support_false() {
155 let capabilities = ClientCapabilities::default();
156 assert!(!capabilities.has_hover_markdown_support());
157 }
158}