mcpls_core/bridge/translator/availability.rs
1//! The closed states a diagnostics answer can be in.
2//!
3//! Shared by `get_diagnostics`, `get_cached_diagnostics` and the diagnostics
4//! resource, so the three report the same state for the same file.
5
6use schemars::JsonSchema;
7use serde::Serialize;
8
9use super::dto::DocumentDiagnosticsResult;
10
11/// Whether the diagnostics cache has an answer for a file.
12///
13/// An empty list under [`Self::Published`] is a real answer: the server said
14/// the file is clean. [`Self::Pending`] and [`Self::Evicted`] carry no answer
15/// at all, so an empty list next to them must not be read as clean.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
17#[serde(rename_all = "snake_case")]
18pub enum DiagnosticsAvailability {
19 /// The server published diagnostics for the file, possibly an empty list.
20 Published,
21 /// Nothing has been published for the file yet.
22 Pending,
23 /// A publish arrived but was dropped to bound the cache, so what the
24 /// server last said about the file is no longer known.
25 Evicted,
26}
27
28/// Where a `get_diagnostics` answer came from.
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
30#[serde(rename_all = "snake_case")]
31pub enum DiagnosticsOrigin {
32 /// A `textDocument/diagnostic` pull, merged with the push cache.
33 Pull,
34 /// The push cache alone, because the server advertises no pull provider.
35 PushCache,
36 /// The pull request failed, so the push cache and the last stored pull answered.
37 CacheAfterFailedPull,
38}
39
40/// A `get_diagnostics` answer together with the state the cache was in when
41/// it was read.
42///
43/// The state is taken under the same cache lock as the snapshot the result
44/// was merged from, so the two cannot disagree.
45#[derive(Debug)]
46pub struct DiagnosticsAnswer {
47 /// The diagnostics of the file.
48 pub result: DocumentDiagnosticsResult,
49 /// Whether the cache has an answer for the file.
50 pub availability: DiagnosticsAvailability,
51 /// Where the answer came from.
52 pub origin: DiagnosticsOrigin,
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_availability_wire_names() {
61 for (value, name) in [
62 (DiagnosticsAvailability::Published, "published"),
63 (DiagnosticsAvailability::Pending, "pending"),
64 (DiagnosticsAvailability::Evicted, "evicted"),
65 ] {
66 assert_eq!(serde_json::to_value(value).unwrap(), name);
67 }
68 }
69
70 #[test]
71 fn test_origin_wire_names() {
72 assert_eq!(
73 serde_json::to_value(DiagnosticsOrigin::Pull).unwrap(),
74 "pull"
75 );
76 assert_eq!(
77 serde_json::to_value(DiagnosticsOrigin::PushCache).unwrap(),
78 "push_cache"
79 );
80 assert_eq!(
81 serde_json::to_value(DiagnosticsOrigin::CacheAfterFailedPull).unwrap(),
82 "cache_after_failed_pull"
83 );
84 }
85}