gestura_core_tools/
code_async.rs1use crate::code::{CodeTools, EditOp};
7use crate::error::AppError;
8use crate::error::Result;
9use std::path::Path;
10
11fn to_json<T: serde::Serialize>(val: &T) -> Result<String> {
13 serde_json::to_string_pretty(val)
14 .map_err(|e| AppError::Io(std::io::Error::other(format!("Serialize error: {e}"))))
15}
16
17fn join_err(e: tokio::task::JoinError) -> AppError {
19 AppError::Io(std::io::Error::other(format!("Task join error: {e}")))
20}
21
22pub async fn stats_dir(path: &str) -> Result<String> {
24 let path = path.to_string();
25 tokio::task::spawn_blocking(move || {
26 let tools = CodeTools::default();
27 let stats = tools.stats(Path::new(&path))?;
28 to_json(&serde_json::json!({ "path": path, "stats": stats }))
29 })
30 .await
31 .map_err(join_err)?
32}
33
34pub async fn map(path: &str, max_depth: usize) -> Result<String> {
36 let path = path.to_string();
37 tokio::task::spawn_blocking(move || {
38 let tools = CodeTools::default();
39 let result = tools.repository_map(Path::new(&path), max_depth)?;
40 to_json(&result)
41 })
42 .await
43 .map_err(join_err)?
44}
45
46pub async fn symbols(path: &str) -> Result<String> {
48 let path = path.to_string();
49 tokio::task::spawn_blocking(move || {
50 let tools = CodeTools::default();
51 let result = tools.symbols(Path::new(&path))?;
52 to_json(&result)
53 })
54 .await
55 .map_err(join_err)?
56}
57
58pub async fn references(symbol: &str, root: &str) -> Result<String> {
60 let symbol = symbol.to_string();
61 let root = root.to_string();
62 tokio::task::spawn_blocking(move || {
63 let tools = CodeTools::default();
64 let result = tools.references(&symbol, Path::new(&root))?;
65 to_json(&result)
66 })
67 .await
68 .map_err(join_err)?
69}
70
71pub async fn definition(symbol: &str, root: &str) -> Result<String> {
73 let symbol = symbol.to_string();
74 let root = root.to_string();
75 tokio::task::spawn_blocking(move || {
76 let tools = CodeTools::default();
77 let result = tools.definition(&symbol, Path::new(&root))?;
78 to_json(&result)
79 })
80 .await
81 .map_err(join_err)?
82}
83
84pub async fn deps(path: &str) -> Result<String> {
86 let path = path.to_string();
87 tokio::task::spawn_blocking(move || {
88 let tools = CodeTools::default();
89 let result = tools.cargo_dependencies(Path::new(&path))?;
90 to_json(&result)
91 })
92 .await
93 .map_err(join_err)?
94}
95
96pub async fn lint(path: &str, fix: bool) -> Result<String> {
98 let path = path.to_string();
99 tokio::task::spawn_blocking(move || {
100 let tools = CodeTools::default();
101 let result = tools.cargo_clippy(Path::new(&path), fix)?;
102 to_json(&result)
103 })
104 .await
105 .map_err(join_err)?
106}
107
108pub async fn test(path: &str, filter: Option<String>) -> Result<String> {
110 let path = path.to_string();
111 tokio::task::spawn_blocking(move || {
112 let tools = CodeTools::default();
113 let result = tools.cargo_test(Path::new(&path), filter.as_deref())?;
114 to_json(&result)
115 })
116 .await
117 .map_err(join_err)?
118}
119
120pub async fn glob_search(pattern: &str, root: &str, max_results: usize) -> Result<String> {
122 let pattern = pattern.to_string();
123 let root = root.to_string();
124 tokio::task::spawn_blocking(move || {
125 let tools = CodeTools::default();
126 let result = tools.glob_search(&pattern, Path::new(&root), max_results)?;
127 to_json(&result)
128 })
129 .await
130 .map_err(join_err)?
131}
132
133pub async fn grep(
135 pattern: &str,
136 root: &str,
137 file_glob: Option<String>,
138 context_lines: usize,
139 case_sensitive: bool,
140 max_matches: usize,
141) -> Result<String> {
142 let pattern = pattern.to_string();
143 let root = root.to_string();
144 tokio::task::spawn_blocking(move || {
145 let tools = CodeTools::default();
146 let result = tools.grep(
147 &pattern,
148 Path::new(&root),
149 file_glob.as_deref(),
150 context_lines,
151 case_sensitive,
152 max_matches,
153 )?;
154 to_json(&result)
155 })
156 .await
157 .map_err(join_err)?
158}
159
160pub async fn batch_read(paths: Vec<String>) -> Result<String> {
162 tokio::task::spawn_blocking(move || {
163 let tools = CodeTools::default();
164 let path_refs: Vec<&str> = paths.iter().map(|s| s.as_str()).collect();
165 let result = tools.batch_read(&path_refs);
166 to_json(&result)
167 })
168 .await
169 .map_err(join_err)?
170}
171
172pub async fn batch_edit(edits: Vec<EditOp>) -> Result<String> {
174 tokio::task::spawn_blocking(move || {
175 let tools = CodeTools::default();
176 let result = tools.batch_edit(&edits);
177 to_json(&result)
178 })
179 .await
180 .map_err(join_err)?
181}
182
183pub async fn outline(path: &str) -> Result<String> {
185 let path = path.to_string();
186 tokio::task::spawn_blocking(move || {
187 let tools = CodeTools::default();
188 let result = tools.outline(Path::new(&path))?;
189 to_json(&result)
190 })
191 .await
192 .map_err(join_err)?
193}