lsp_types/
document_diagnostic.rs

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