Skip to main content

ls_types/
document_diagnostic.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    Diagnostic, DiagnosticTag, PartialResultParams, StaticRegistrationOptions,
7    TextDocumentIdentifier, TextDocumentRegistrationOptions, Uri, WorkDoneProgressOptions,
8    WorkDoneProgressParams,
9};
10
11/// Client capabilities specific to diagnostic pull requests.
12///
13/// @since 3.17.0
14#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
15#[serde(rename_all = "camelCase")]
16pub struct DiagnosticClientCapabilities {
17    /// Whether implementation supports dynamic registration.
18    ///
19    /// If this is set to `true` the client supports the new `(TextDocumentRegistrationOptions &
20    /// StaticRegistrationOptions)` return value for the corresponding server capability as well.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub dynamic_registration: Option<bool>,
23
24    /// Whether the clients supports related documents for document diagnostic pulls.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub related_document_support: Option<bool>,
27
28    /// Whether the clients accepts diagnostics with related information.
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub related_information: Option<bool>,
31
32    /// Client supports the tag property to provide meta data about a diagnostic.
33    /// Clients supporting tags have to handle unknown tags gracefully.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub tag_support: Option<ClientDiagnosticsTagOptions>,
36
37    /// Client supports a codeDescription property.
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub code_description_support: Option<bool>,
40
41    /// Whether code action supports the `data` property which is preserved between a
42    /// `textDocument/publishDiagnostics` and `textDocument/codeAction` request.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub data_support: Option<bool>,
45}
46
47/// @since 3.18.0
48#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub struct ClientDiagnosticsTagOptions {
51    /// The tags supported by the client.
52    value_set: Vec<DiagnosticTag>,
53}
54
55/// Diagnostic options.
56///
57/// @since 3.17.0
58#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
59#[serde(rename_all = "camelCase")]
60pub struct DiagnosticOptions {
61    /// An optional identifier under which the diagnostics are
62    /// managed by the client.
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub identifier: Option<String>,
65
66    /// Whether the language has inter file dependencies, meaning that editing code in one file can
67    /// result in a different diagnostic set in another file. Inter file dependencies are common
68    /// for most programming languages and typically uncommon for linters.
69    pub inter_file_dependencies: bool,
70
71    /// The server provides support for workspace diagnostics as well.
72    pub workspace_diagnostics: bool,
73
74    #[serde(flatten)]
75    pub work_done_progress_options: WorkDoneProgressOptions,
76}
77
78/// Diagnostic registration options.
79///
80/// @since 3.17.0
81#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
82#[serde(rename_all = "camelCase")]
83pub struct DiagnosticRegistrationOptions {
84    #[serde(flatten)]
85    pub text_document_registration_options: TextDocumentRegistrationOptions,
86
87    #[serde(flatten)]
88    pub diagnostic_options: DiagnosticOptions,
89
90    #[serde(flatten)]
91    pub static_registration_options: StaticRegistrationOptions,
92}
93
94#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
95#[serde(untagged)]
96pub enum DiagnosticServerCapabilities {
97    Options(DiagnosticOptions),
98    RegistrationOptions(DiagnosticRegistrationOptions),
99}
100
101/// Parameters of the document diagnostic request.
102///
103/// @since 3.17.0
104#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
105#[serde(rename_all = "camelCase")]
106pub struct DocumentDiagnosticParams {
107    /// The text document.
108    pub text_document: TextDocumentIdentifier,
109
110    /// The additional identifier provided during registration.
111    pub identifier: Option<String>,
112
113    /// The result ID of a previous response if provided.
114    pub previous_result_id: Option<String>,
115
116    #[serde(flatten)]
117    pub work_done_progress_params: WorkDoneProgressParams,
118
119    #[serde(flatten)]
120    pub partial_result_params: PartialResultParams,
121}
122
123/// A diagnostic report with a full set of problems.
124///
125/// @since 3.17.0
126#[derive(Debug, PartialEq, Eq, Default, Deserialize, Serialize, Clone)]
127#[serde(rename_all = "camelCase")]
128pub struct FullDocumentDiagnosticReport {
129    /// An optional result ID. If provided it will be sent on the next diagnostic request for the
130    /// same document.
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub result_id: Option<String>,
133
134    /// The actual items.
135    pub items: Vec<Diagnostic>,
136}
137
138/// A diagnostic report indicating that the last returned report is still accurate.
139///
140/// A server can only return `unchanged` if result ids are provided.
141///
142/// @since 3.17.0
143#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
144#[serde(rename_all = "camelCase")]
145pub struct UnchangedDocumentDiagnosticReport {
146    /// A result ID which will be sent on the next diagnostic request for the same document.
147    pub result_id: String,
148}
149
150/// The document diagnostic report kinds.
151///
152/// @since 3.17.0
153#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
154#[serde(tag = "kind", rename_all = "lowercase")]
155pub enum DocumentDiagnosticReportKind {
156    /// A diagnostic report with a full set of problems.
157    Full(FullDocumentDiagnosticReport),
158    /// A report indicating that the last returned report is still accurate.
159    Unchanged(UnchangedDocumentDiagnosticReport),
160}
161
162impl From<FullDocumentDiagnosticReport> for DocumentDiagnosticReportKind {
163    fn from(from: FullDocumentDiagnosticReport) -> Self {
164        Self::Full(from)
165    }
166}
167
168impl From<UnchangedDocumentDiagnosticReport> for DocumentDiagnosticReportKind {
169    fn from(from: UnchangedDocumentDiagnosticReport) -> Self {
170        Self::Unchanged(from)
171    }
172}
173
174/// A full diagnostic report with a set of related documents.
175///
176/// @since 3.17.0
177#[derive(Debug, PartialEq, Eq, Default, Deserialize, Serialize, Clone)]
178#[serde(rename_all = "camelCase")]
179pub struct RelatedFullDocumentDiagnosticReport {
180    /// Diagnostics of related documents.
181    ///
182    /// This information is useful in programming languages where code in a file A can generate
183    /// diagnostics in a file B which A depends on. An example of such a language is C/C++ where
184    /// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.
185    ///
186    /// @since 3.17.0
187    #[serde(skip_serializing_if = "Option::is_none")]
188    #[serde(default)]
189    pub related_documents: Option<HashMap<Uri, DocumentDiagnosticReportKind>>,
190    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
191    #[serde(flatten)]
192    pub full_document_diagnostic_report: FullDocumentDiagnosticReport,
193}
194
195/// An unchanged diagnostic report with a set of related documents.
196///
197/// @since 3.17.0
198#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
199#[serde(rename_all = "camelCase")]
200pub struct RelatedUnchangedDocumentDiagnosticReport {
201    /// Diagnostics of related documents.
202    ///
203    /// This information is useful in programming languages where code in a file A can generate
204    /// diagnostics in a file B which A depends on. An example of such a language is C/C++ where
205    /// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.
206    ///
207    /// @since 3.17.0
208    #[serde(skip_serializing_if = "Option::is_none")]
209    #[serde(default)]
210    pub related_documents: Option<HashMap<Uri, DocumentDiagnosticReportKind>>,
211    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
212    #[serde(flatten)]
213    pub unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport,
214}
215
216/// The result of a document diagnostic pull request.
217///
218/// A report can either be a full report containing all diagnostics for the requested document or
219/// an unchanged report indicating that nothing has changed in terms of diagnostics in comparison
220/// to the last pull request.
221///
222/// @since 3.17.0
223#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
224#[serde(tag = "kind", rename_all = "lowercase")]
225pub enum DocumentDiagnosticReport {
226    /// A diagnostic report with a full set of problems.
227    Full(RelatedFullDocumentDiagnosticReport),
228    /// A report indicating that the last returned report is still accurate.
229    Unchanged(RelatedUnchangedDocumentDiagnosticReport),
230}
231
232impl From<RelatedFullDocumentDiagnosticReport> for DocumentDiagnosticReport {
233    fn from(from: RelatedFullDocumentDiagnosticReport) -> Self {
234        Self::Full(from)
235    }
236}
237
238impl From<RelatedUnchangedDocumentDiagnosticReport> for DocumentDiagnosticReport {
239    fn from(from: RelatedUnchangedDocumentDiagnosticReport) -> Self {
240        Self::Unchanged(from)
241    }
242}
243
244/// A partial result for a document diagnostic report.
245///
246/// @since 3.17.0
247#[derive(Debug, PartialEq, Eq, Default, Deserialize, Serialize, Clone)]
248#[serde(rename_all = "camelCase")]
249pub struct DocumentDiagnosticReportPartialResult {
250    #[serde(skip_serializing_if = "Option::is_none")]
251    #[serde(default)]
252    pub related_documents: Option<HashMap<Uri, DocumentDiagnosticReportKind>>,
253    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
254}
255
256#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
257#[serde(untagged)]
258pub enum DocumentDiagnosticReportResult {
259    Report(DocumentDiagnosticReport),
260    Partial(DocumentDiagnosticReportPartialResult),
261}
262
263impl From<DocumentDiagnosticReport> for DocumentDiagnosticReportResult {
264    fn from(from: DocumentDiagnosticReport) -> Self {
265        Self::Report(from)
266    }
267}
268
269impl From<DocumentDiagnosticReportPartialResult> for DocumentDiagnosticReportResult {
270    fn from(from: DocumentDiagnosticReportPartialResult) -> Self {
271        Self::Partial(from)
272    }
273}
274
275/// Cancellation data returned from a diagnostic request.
276///
277/// If no data is provided, it defaults to `{ retrigger_request: true }`.
278///
279/// @since 3.17.0
280#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
281#[serde(rename_all = "camelCase")]
282pub struct DiagnosticServerCancellationData {
283    pub retrigger_request: bool,
284}
285
286impl Default for DiagnosticServerCancellationData {
287    fn default() -> Self {
288        Self {
289            retrigger_request: true,
290        }
291    }
292}