Skip to main content

lspkit_server/
capabilities.rs

1//! Server-capability builder.
2//!
3//! Wraps the LSP protocol's capability advertisement so consumers do not
4//! depend on a specific protocol-types crate version in their public API.
5
6use std::collections::BTreeSet;
7
8use lspkit_vfs::PositionEncoding;
9
10/// Kind of text-document synchronization the server supports.
11#[non_exhaustive]
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13pub enum TextSync {
14    /// No synchronization.
15    None,
16    /// Full text on every change. Simple but expensive.
17    Full,
18    /// Incremental edits.
19    #[default]
20    Incremental,
21}
22
23/// A single advertised feature.
24#[non_exhaustive]
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
26pub enum Feature {
27    /// `textDocument/completion`.
28    Completion,
29    /// `textDocument/hover`.
30    Hover,
31    /// `textDocument/definition`.
32    Definition,
33    /// `textDocument/references`.
34    References,
35    /// Pull-style `textDocument/diagnostic`.
36    DiagnosticsPull,
37}
38
39/// Builder for the server's advertised capabilities.
40#[non_exhaustive]
41#[derive(Debug, Clone)]
42pub struct Capabilities {
43    encoding: PositionEncoding,
44    text_sync: TextSync,
45    features: BTreeSet<Feature>,
46}
47
48impl Capabilities {
49    /// Builder seeded with sensible defaults: incremental sync, UTF-16, no features.
50    #[must_use]
51    pub fn new() -> Self {
52        Self {
53            encoding: PositionEncoding::default(),
54            text_sync: TextSync::default(),
55            features: BTreeSet::new(),
56        }
57    }
58
59    /// Set the negotiated position encoding.
60    #[must_use]
61    pub fn position_encoding(mut self, encoding: PositionEncoding) -> Self {
62        self.encoding = encoding;
63        self
64    }
65
66    /// Set the text-document synchronization kind.
67    #[must_use]
68    pub fn text_sync(mut self, kind: TextSync) -> Self {
69        self.text_sync = kind;
70        self
71    }
72
73    /// Advertise `feature`.
74    #[must_use]
75    pub fn enable(mut self, feature: Feature) -> Self {
76        self.features.insert(feature);
77        self
78    }
79
80    /// Whether `feature` is advertised.
81    #[must_use]
82    pub fn has(&self, feature: Feature) -> bool {
83        self.features.contains(&feature)
84    }
85
86    /// The negotiated position encoding.
87    #[must_use]
88    pub fn encoding(&self) -> PositionEncoding {
89        self.encoding
90    }
91
92    /// The text-sync kind.
93    #[must_use]
94    pub fn text_sync_kind(&self) -> TextSync {
95        self.text_sync
96    }
97
98    /// Snapshot the advertised features.
99    #[must_use]
100    pub fn features(&self) -> Vec<Feature> {
101        self.features.iter().copied().collect()
102    }
103}
104
105impl Default for Capabilities {
106    fn default() -> Self {
107        Self::new()
108    }
109}