1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Serialize, Deserialize)]
5pub struct DaemonStatusResponse {
6 pub ready: bool,
7 pub indexed_at: Option<String>,
8 pub workspace_root: String,
9 pub process_id: u32,
10}
11
12#[derive(Debug, Serialize, Deserialize)]
13pub struct SymbolQueryRequest {
14 pub name: String,
15 pub kind: String,
16 pub exact: bool,
17}
18
19#[derive(Debug, Serialize, Deserialize)]
20pub struct SymbolItem {
21 pub name: String,
22 pub kind: String,
23 pub file: String,
24 pub line: u32,
25 pub col: u32,
26 pub container_name: Option<String>,
27}
28
29#[derive(Debug, Serialize, Deserialize)]
30pub struct OutlineQueryRequest {
31 pub file: PathBuf,
32}
33
34#[derive(Debug, Serialize, Deserialize)]
35pub struct OutlineItem {
36 pub name: String,
37 pub kind: String,
38 pub detail: Option<String>,
39 pub line: u32,
40 pub col: u32,
41 pub end_line: u32,
42 pub children: Vec<OutlineItem>,
43}
44
45#[derive(Debug, Serialize, Deserialize)]
46pub struct DefinitionQueryRequest {
47 pub file: PathBuf,
48 pub line: u32,
49 pub col: u32,
50}
51
52#[derive(Debug, Serialize, Deserialize)]
53pub struct DefinitionItem {
54 pub file: String,
55 pub line: u32,
56 pub col: u32,
57 pub end_line: u32,
58 pub end_col: u32,
59 pub snippet: Option<String>,
60}
61
62#[derive(Debug, Serialize, Deserialize)]
63pub struct CursorQueryRequest {
64 pub file: PathBuf,
65 pub line: u32,
66 pub col: u32,
67 pub mode: String, pub depth: u32,
69}
70
71#[derive(Debug, Serialize, Deserialize)]
72pub struct CursorItem {
73 pub name: String,
74 pub kind: String,
75 pub file: String,
76 pub line: u32,
77 pub col: u32,
78 pub caller_or_callee: Option<String>,
79}
80
81#[derive(Debug, Serialize, Deserialize)]
82pub struct TypeHierarchyQueryRequest {
83 pub file: PathBuf,
84 pub line: u32,
85 pub col: u32,
86 pub mode: String, pub depth: u32,
88}
89
90#[derive(Debug, Serialize, Deserialize)]
91pub struct TypeHierarchyItemResult {
92 pub name: String,
93 pub kind: String,
94 pub file: String,
95 pub line: u32,
96 pub col: u32,
97 pub detail: Option<String>,
98}
99
100
101#[derive(Debug, Serialize, Deserialize)]
102pub struct CheckQueryRequest {
103 pub target: Option<String>,
104}
105
106#[derive(Debug, Serialize, Deserialize)]
107pub struct CheckDiagnosticItem {
108 pub message: String,
109 pub level: String, pub file: Option<String>,
111 pub line: Option<u32>,
112 pub col: Option<u32>,
113}
114
115#[derive(Debug, Serialize, Deserialize)]
116pub struct CheckResponse {
117 pub success: bool,
118 pub diagnostics: Vec<CheckDiagnosticItem>,
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_daemon_status_json_roundtrip() {
127 let status = DaemonStatusResponse {
128 ready: true,
129 indexed_at: Some("2026-07-31T10:00:00Z".to_string()),
130 workspace_root: "/path/to/workspace".to_string(),
131 process_id: 12345,
132 };
133 let json = serde_json::to_string(&status).unwrap();
134 let decoded: DaemonStatusResponse = serde_json::from_str(&json).unwrap();
135 assert!(decoded.ready);
136 assert_eq!(decoded.process_id, 12345);
137 assert_eq!(decoded.workspace_root, "/path/to/workspace");
138 }
139
140 #[test]
141 fn test_symbol_item_json_roundtrip() {
142 let item = SymbolItem {
143 name: "LspClient".to_string(),
144 kind: "struct".to_string(),
145 file: "src/lsp/client.rs".to_string(),
146 line: 15,
147 col: 1,
148 container_name: Some("lsp".to_string()),
149 };
150 let json = serde_json::to_string(&item).unwrap();
151 let decoded: SymbolItem = serde_json::from_str(&json).unwrap();
152 assert_eq!(decoded.name, "LspClient");
153 assert_eq!(decoded.kind, "struct");
154 }
155}
156