Skip to main content

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}