haystack_server/ops/
ops_handler.rs1use actix_web::{HttpRequest, HttpResponse, web};
20
21use haystack_core::data::{HCol, HDict, HGrid};
22use haystack_core::kinds::Kind;
23
24use crate::content;
25use crate::state::AppState;
26
27pub async fn handle(req: HttpRequest, _state: web::Data<AppState>) -> HttpResponse {
29 let accept = req
30 .headers()
31 .get("Accept")
32 .and_then(|v| v.to_str().ok())
33 .unwrap_or("");
34
35 let ops = vec![
36 ("about", "Summary information for server"),
37 ("ops", "Operations supported by this server"),
38 ("formats", "Grid data formats supported by this server"),
39 ("read", "Read entity records by id or filter"),
40 ("nav", "Navigate a project for discovery"),
41 ("defs", "Query the definitions namespace"),
42 ("libs", "Query the library namespace"),
43 ("watchSub", "Subscribe to entity changes"),
44 ("watchPoll", "Poll for entity changes"),
45 ("watchUnsub", "Unsubscribe from entity changes"),
46 ("pointWrite", "Write a value to a writable point"),
47 ("hisRead", "Read historical time-series data"),
48 ("hisWrite", "Write historical time-series data"),
49 ("invokeAction", "Invoke an action on an entity"),
50 ("close", "Close the current session"),
51 (
52 "graph/flow",
53 "Full graph as nodes + edges for visualization",
54 ),
55 ("graph/edges", "All ref relationships as explicit edges"),
56 ("graph/tree", "Recursive subtree from a root entity"),
57 ("graph/neighbors", "N-hop neighborhood around an entity"),
58 ("graph/path", "Shortest path between two entities"),
59 ("graph/stats", "Graph metrics and statistics"),
60 ];
61
62 let cols = vec![HCol::new("name"), HCol::new("summary")];
63 let rows: Vec<HDict> = ops
64 .into_iter()
65 .map(|(name, summary)| {
66 let mut row = HDict::new();
67 row.set("name", Kind::Str(name.to_string()));
68 row.set("summary", Kind::Str(summary.to_string()));
69 row
70 })
71 .collect();
72
73 let grid = HGrid::from_parts(HDict::new(), cols, rows);
74 match content::encode_response_grid(&grid, accept) {
75 Ok((body, ct)) => HttpResponse::Ok().content_type(ct).body(body),
76 Err(e) => {
77 log::error!("Failed to encode ops grid: {e}");
78 HttpResponse::InternalServerError().body("encoding error")
79 }
80 }
81}