aft/commands/
trace_data.rs1use std::path::Path;
2
3use crate::context::AppContext;
4use crate::protocol::{RawRequest, Response};
5
6pub fn handle_trace_data(req: &RawRequest, ctx: &AppContext) -> Response {
27 let file = match req.params.get("file").and_then(|v| v.as_str()) {
28 Some(f) => f,
29 None => {
30 return Response::error(
31 &req.id,
32 "invalid_request",
33 "trace_data: missing required param 'file'",
34 );
35 }
36 };
37
38 let symbol = match req.params.get("symbol").and_then(|v| v.as_str()) {
39 Some(s) => s,
40 None => {
41 return Response::error(
42 &req.id,
43 "invalid_request",
44 "trace_data: missing required param 'symbol'",
45 );
46 }
47 };
48
49 let expression = match req.params.get("expression").and_then(|v| v.as_str()) {
50 Some(e) => e,
51 None => {
52 return Response::error(
53 &req.id,
54 "invalid_request",
55 "trace_data: missing required param 'expression'",
56 );
57 }
58 };
59
60 let depth = req
61 .params
62 .get("depth")
63 .and_then(|v| v.as_u64())
64 .unwrap_or(5)
65 .min(100) as usize;
66
67 let mut cg_ref = ctx.callgraph().borrow_mut();
68 let graph = match cg_ref.as_mut() {
69 Some(g) => g,
70 None => {
71 return Response::error(
72 &req.id,
73 "not_configured",
74 "trace_data: project not configured — send 'configure' first",
75 );
76 }
77 };
78
79 let file_path = Path::new(file);
80
81 match graph.build_file(file_path) {
83 Ok(data) => {
84 let has_symbol = data.calls_by_symbol.contains_key(symbol)
85 || data.exported_symbols.contains(&symbol.to_string())
86 || data.symbol_metadata.contains_key(symbol);
87 if !has_symbol {
88 return Response::error(
89 &req.id,
90 "symbol_not_found",
91 format!("trace_data: symbol '{}' not found in {}", symbol, file),
92 );
93 }
94 }
95 Err(e) => {
96 return Response::error(&req.id, e.code(), e.to_string());
97 }
98 }
99
100 match graph.trace_data(file_path, symbol, expression, depth) {
101 Ok(result) => {
102 let result_json = serde_json::to_value(&result).unwrap_or_default();
103 Response::success(&req.id, result_json)
104 }
105 Err(e) => Response::error(&req.id, e.code(), e.to_string()),
106 }
107}