tawasuyu/llimphi
Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.
⎇ 92dd0e5bfb2ca4456006da99437f4100e156d856
widgets/text-editor-core/src/diagnostics.rs
History
Who touched what
raw
feat: llimphi standalone — framework UI soberano extraído del monorepo
1//! Diagnósticos del editor — espejo minimal del shape de `lsp-types`
2//! sin depender del crate. Pensado para que un client LSP (rust-analyzer,
3//! pylsp, etc.) lo poble desde fuera; el render del editor los pinta
4//! como subrayado bajo el rango.
5//!
6//! El client real vive aparte (proceso + JSON-RPC) — este módulo sólo
7//! define el shape de los datos y el helper para renderizarlos.
8
9use crate::cursor::Pos;
10
11/// Severidad — mismos valores y orden que en LSP (1 = Error es el más alto).
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum Severity {
14 Error,
15 Warning,
16 Information,
17 Hint,
18}
19
20/// Rango cerrado de un diagnostic. `end` exclusivo en `col`.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct DiagnosticRange {
23 pub start: Pos,
24 pub end: Pos,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct Diagnostic {
29 pub range: DiagnosticRange,
30 pub severity: Severity,
31 /// Mensaje humano corto — el render lo trunca para mostrar al hover/
32 /// en una mini popup futura. En esta versión solo se usa el rango.
33 pub message: String,
34 /// Source del diagnostic — "rust-analyzer", "pylsp", "clippy", etc.
35 /// `None` si no se conoce.
36 pub source: Option<String>,
37}
38
39impl Diagnostic {
40 pub fn error(line_start: usize, col_start: usize, line_end: usize, col_end: usize, message: impl Into<String>) -> Self {
41 Self {
42 range: DiagnosticRange {
43 start: Pos::new(line_start, col_start),
44 end: Pos::new(line_end, col_end),
45 },
46 severity: Severity::Error,
47 message: message.into(),
48 source: None,
49 }
50 }
51 pub fn warning(line_start: usize, col_start: usize, line_end: usize, col_end: usize, message: impl Into<String>) -> Self {
52 Self {
53 range: DiagnosticRange {
54 start: Pos::new(line_start, col_start),
55 end: Pos::new(line_end, col_end),
56 },
57 severity: Severity::Warning,
58 message: message.into(),
59 source: None,
60 }
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn constructors_funcionan() {
70 let e = Diagnostic::error(1, 2, 1, 5, "boom");
71 assert_eq!(e.severity, Severity::Error);
72 assert_eq!(e.range.start, Pos::new(1, 2));
73 assert_eq!(e.range.end, Pos::new(1, 5));
74
75 let w = Diagnostic::warning(0, 0, 0, 10, "ojo");
76 assert_eq!(w.severity, Severity::Warning);
77 }
78}