Skip to main content

eure_ls/
types.rs

1//! Core types for the Eure Language Server.
2//!
3//! This module contains types shared between native and WASM implementations.
4
5use std::collections::HashSet;
6
7#[cfg(not(target_arch = "wasm32"))]
8use eure::query::TextFileContent;
9use eure::query::{Glob, TextFile};
10use query_flow::RevisionCounter;
11use serde_json::Value;
12
13use crate::queries::{LspDiagnostics, LspFileDiagnostics, LspSemanticTokens};
14
15/// Platform-agnostic request ID.
16///
17/// LSP allows request IDs to be either integers or strings.
18#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
19#[serde(untagged)]
20pub enum CoreRequestId {
21    Int(i32),
22    Str(String),
23}
24
25impl CoreRequestId {
26    pub fn as_str(&self) -> String {
27        match self {
28            CoreRequestId::Int(n) => n.to_string(),
29            CoreRequestId::Str(s) => s.clone(),
30        }
31    }
32}
33
34impl From<i32> for CoreRequestId {
35    fn from(n: i32) -> Self {
36        CoreRequestId::Int(n)
37    }
38}
39
40impl From<String> for CoreRequestId {
41    fn from(s: String) -> Self {
42        CoreRequestId::Str(s)
43    }
44}
45
46impl From<&str> for CoreRequestId {
47    fn from(s: &str) -> Self {
48        CoreRequestId::Str(s.to_string())
49    }
50}
51
52impl From<&Value> for CoreRequestId {
53    fn from(v: &Value) -> Self {
54        serde_json::from_value(v.clone()).unwrap()
55    }
56}
57
58#[cfg(not(target_arch = "wasm32"))]
59impl From<lsp_server::RequestId> for CoreRequestId {
60    fn from(id: lsp_server::RequestId) -> Self {
61        serde_json::from_value(serde_json::to_value(&id).unwrap()).unwrap()
62    }
63}
64
65#[cfg(not(target_arch = "wasm32"))]
66impl From<&CoreRequestId> for lsp_server::RequestId {
67    fn from(id: &CoreRequestId) -> Self {
68        serde_json::from_value(serde_json::to_value(id).unwrap()).unwrap()
69    }
70}
71
72/// Effects the core needs the platform to perform.
73#[derive(Debug, Clone)]
74pub enum Effect {
75    /// Request to fetch a file's content.
76    FetchFile(TextFile),
77    /// Request to expand a glob pattern.
78    ExpandGlob {
79        /// Unique identifier for this glob request.
80        id: String,
81        /// The glob pattern to expand.
82        glob: Glob,
83    },
84}
85
86/// LSP error information.
87#[derive(Debug, Clone)]
88pub struct LspError {
89    pub code: i32,
90    pub message: String,
91}
92
93impl LspError {
94    pub fn new(code: i32, message: impl Into<String>) -> Self {
95        Self {
96            code,
97            message: message.into(),
98        }
99    }
100
101    pub fn internal_error(message: impl Into<String>) -> Self {
102        Self::new(-32603, message)
103    }
104
105    pub fn invalid_params(message: impl Into<String>) -> Self {
106        Self::new(-32602, message)
107    }
108
109    pub fn method_not_found(method: &str) -> Self {
110        Self::new(-32601, format!("Method not found: {}", method))
111    }
112}
113
114/// Output messages from the core.
115#[derive(Debug, Clone)]
116pub enum LspOutput {
117    /// Response to a request.
118    Response {
119        id: CoreRequestId,
120        result: Result<Value, LspError>,
121    },
122    /// Notification to send to client.
123    Notification { method: String, params: Value },
124}
125
126/// LSP commands wrapping query structs generated by #[query] macro.
127#[derive(Clone)]
128pub enum CommandQuery {
129    SemanticTokensFull(LspSemanticTokens),
130}
131
132/// Result of executing a command query.
133pub enum CommandResult {
134    SemanticTokens(Option<lsp_types::SemanticTokens>),
135}
136
137/// A pending LSP request waiting for assets to be resolved.
138pub struct PendingRequest {
139    /// The request ID.
140    pub id: CoreRequestId,
141    /// The command to execute.
142    pub command: CommandQuery,
143    /// Assets this request is waiting for.
144    pub waiting_for: HashSet<TextFile>,
145}
146
147/// Subscription for diagnostics with revision tracking (legacy per-URI).
148#[derive(Clone)]
149pub struct DiagnosticsSubscription {
150    pub query: LspDiagnostics,
151    pub last_revision: RevisionCounter,
152}
153
154/// Per-file diagnostics subscription with revision tracking.
155///
156/// Used for the new per-file polling approach where each file
157/// has its own subscription and revision counter.
158#[derive(Clone)]
159pub struct FileDiagnosticsSubscription {
160    pub file: TextFile,
161    pub query: LspFileDiagnostics,
162    pub last_revision: RevisionCounter,
163}
164
165// Native-only types for I/O operations
166
167/// Request to read a file from disk.
168#[cfg(not(target_arch = "wasm32"))]
169pub struct IoRequest {
170    pub file: TextFile,
171}
172
173/// Response from reading a file.
174#[cfg(not(target_arch = "wasm32"))]
175pub struct IoResponse {
176    pub file: TextFile,
177    /// Content or error from fetching the file.
178    pub result: Result<TextFileContent, anyhow::Error>,
179}