Skip to main content

ls_types/
document_diagnostic.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    Diagnostic, PartialResultParams, StaticRegistrationOptions, TextDocumentIdentifier,
7    TextDocumentRegistrationOptions, Uri, WorkDoneProgressOptions, WorkDoneProgressParams,
8    macros::lsp_enum,
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/// The diagnostic tags.
56///
57/// @since 3.15.0
58#[derive(Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
59#[serde(transparent)]
60pub struct DiagnosticTag(u32);
61
62lsp_enum! {
63    impl DiagnosticTag {
64        /// Unused or unnecessary code.
65        ///
66        /// Clients are allowed to render diagnostics with this tag faded out
67        /// instead of having an error squiggle.
68        const UNNECESSARY = 1;
69        /// Deprecated or obsolete code.
70        ///
71        /// Clients are allowed to rendered diagnostics with this tag strike through.
72        const DEPRECATED = 2;
73    }
74}
75
76/// Diagnostic options.
77///
78/// @since 3.17.0
79#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
80#[serde(rename_all = "camelCase")]
81pub struct DiagnosticOptions {
82    /// An optional identifier under which the diagnostics are
83    /// managed by the client.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub identifier: Option<String>,
86
87    /// Whether the language has inter file dependencies, meaning that editing code in one file can
88    /// result in a different diagnostic set in another file. Inter file dependencies are common
89    /// for most programming languages and typically uncommon for linters.
90    pub inter_file_dependencies: bool,
91
92    /// The server provides support for workspace diagnostics as well.
93    pub workspace_diagnostics: bool,
94
95    #[serde(flatten)]
96    pub work_done_progress_options: WorkDoneProgressOptions,
97}
98
99/// Diagnostic registration options.
100///
101/// @since 3.17.0
102#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
103#[serde(rename_all = "camelCase")]
104pub struct DiagnosticRegistrationOptions {
105    #[serde(flatten)]
106    pub text_document_registration_options: TextDocumentRegistrationOptions,
107
108    #[serde(flatten)]
109    pub diagnostic_options: DiagnosticOptions,
110
111    #[serde(flatten)]
112    pub static_registration_options: StaticRegistrationOptions,
113}
114
115#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
116#[serde(untagged)]
117pub enum DiagnosticServerCapabilities {
118    Options(DiagnosticOptions),
119    RegistrationOptions(DiagnosticRegistrationOptions),
120}
121
122/// Parameters of the document diagnostic request.
123///
124/// @since 3.17.0
125#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
126#[serde(rename_all = "camelCase")]
127pub struct DocumentDiagnosticParams {
128    /// The text document.
129    pub text_document: TextDocumentIdentifier,
130
131    /// The additional identifier provided during registration.
132    pub identifier: Option<String>,
133
134    /// The result ID of a previous response if provided.
135    pub previous_result_id: Option<String>,
136
137    #[serde(flatten)]
138    pub work_done_progress_params: WorkDoneProgressParams,
139
140    #[serde(flatten)]
141    pub partial_result_params: PartialResultParams,
142}
143
144/// A diagnostic report with a full set of problems.
145///
146/// @since 3.17.0
147#[derive(Debug, PartialEq, Eq, Default, Deserialize, Serialize, Clone)]
148#[serde(rename_all = "camelCase")]
149pub struct FullDocumentDiagnosticReport {
150    /// An optional result ID. If provided it will be sent on the next diagnostic request for the
151    /// same document.
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub result_id: Option<String>,
154
155    /// The actual items.
156    pub items: Vec<Diagnostic>,
157}
158
159/// A diagnostic report indicating that the last returned report is still accurate.
160///
161/// A server can only return `unchanged` if result ids are provided.
162///
163/// @since 3.17.0
164#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
165#[serde(rename_all = "camelCase")]
166pub struct UnchangedDocumentDiagnosticReport {
167    /// A result ID which will be sent on the next diagnostic request for the same document.
168    pub result_id: String,
169}
170
171/// The document diagnostic report kinds.
172///
173/// @since 3.17.0
174#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
175#[serde(tag = "kind", rename_all = "lowercase")]
176pub enum DocumentDiagnosticReportKind {
177    /// A diagnostic report with a full set of problems.
178    Full(FullDocumentDiagnosticReport),
179    /// A report indicating that the last returned report is still accurate.
180    Unchanged(UnchangedDocumentDiagnosticReport),
181}
182
183impl From<FullDocumentDiagnosticReport> for DocumentDiagnosticReportKind {
184    fn from(from: FullDocumentDiagnosticReport) -> Self {
185        Self::Full(from)
186    }
187}
188
189impl From<UnchangedDocumentDiagnosticReport> for DocumentDiagnosticReportKind {
190    fn from(from: UnchangedDocumentDiagnosticReport) -> Self {
191        Self::Unchanged(from)
192    }
193}
194
195/// A full diagnostic report with a set of related documents.
196///
197/// @since 3.17.0
198#[derive(Debug, PartialEq, Eq, Default, Deserialize, Serialize, Clone)]
199#[serde(rename_all = "camelCase")]
200pub struct RelatedFullDocumentDiagnosticReport {
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 full_document_diagnostic_report: FullDocumentDiagnosticReport,
214}
215
216/// An unchanged diagnostic report with a set of related documents.
217///
218/// @since 3.17.0
219#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
220#[serde(rename_all = "camelCase")]
221pub struct RelatedUnchangedDocumentDiagnosticReport {
222    /// Diagnostics of related documents.
223    ///
224    /// This information is useful in programming languages where code in a file A can generate
225    /// diagnostics in a file B which A depends on. An example of such a language is C/C++ where
226    /// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.
227    ///
228    /// @since 3.17.0
229    #[serde(skip_serializing_if = "Option::is_none")]
230    #[serde(default)]
231    pub related_documents: Option<HashMap<Uri, DocumentDiagnosticReportKind>>,
232    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
233    #[serde(flatten)]
234    pub unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport,
235}
236
237/// The result of a document diagnostic pull request.
238///
239/// A report can either be a full report containing all diagnostics for the requested document or
240/// an unchanged report indicating that nothing has changed in terms of diagnostics in comparison
241/// to the last pull request.
242///
243/// @since 3.17.0
244#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
245#[serde(tag = "kind", rename_all = "lowercase")]
246pub enum DocumentDiagnosticReport {
247    /// A diagnostic report with a full set of problems.
248    Full(RelatedFullDocumentDiagnosticReport),
249    /// A report indicating that the last returned report is still accurate.
250    Unchanged(RelatedUnchangedDocumentDiagnosticReport),
251}
252
253impl From<RelatedFullDocumentDiagnosticReport> for DocumentDiagnosticReport {
254    fn from(from: RelatedFullDocumentDiagnosticReport) -> Self {
255        Self::Full(from)
256    }
257}
258
259impl From<RelatedUnchangedDocumentDiagnosticReport> for DocumentDiagnosticReport {
260    fn from(from: RelatedUnchangedDocumentDiagnosticReport) -> Self {
261        Self::Unchanged(from)
262    }
263}
264
265/// A partial result for a document diagnostic report.
266///
267/// @since 3.17.0
268#[derive(Debug, PartialEq, Eq, Default, Deserialize, Serialize, Clone)]
269#[serde(rename_all = "camelCase")]
270pub struct DocumentDiagnosticReportPartialResult {
271    #[serde(skip_serializing_if = "Option::is_none")]
272    #[serde(default)]
273    pub related_documents: Option<HashMap<Uri, DocumentDiagnosticReportKind>>,
274    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
275}
276
277#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
278#[serde(untagged)]
279pub enum DocumentDiagnosticReportResult {
280    Report(DocumentDiagnosticReport),
281    Partial(DocumentDiagnosticReportPartialResult),
282}
283
284impl From<DocumentDiagnosticReport> for DocumentDiagnosticReportResult {
285    fn from(from: DocumentDiagnosticReport) -> Self {
286        Self::Report(from)
287    }
288}
289
290impl From<DocumentDiagnosticReportPartialResult> for DocumentDiagnosticReportResult {
291    fn from(from: DocumentDiagnosticReportPartialResult) -> Self {
292        Self::Partial(from)
293    }
294}
295
296/// Cancellation data returned from a diagnostic request.
297///
298/// If no data is provided, it defaults to `{ retrigger_request: true }`.
299///
300/// @since 3.17.0
301#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
302#[serde(rename_all = "camelCase")]
303pub struct DiagnosticServerCancellationData {
304    pub retrigger_request: bool,
305}
306
307impl Default for DiagnosticServerCancellationData {
308    fn default() -> Self {
309        Self {
310            retrigger_request: true,
311        }
312    }
313}