haystack_server/ops/
federation.rs1use actix_web::{HttpRequest, HttpResponse, web};
4
5use haystack_core::data::{HCol, HDict, HGrid};
6use haystack_core::kinds::{Kind, Number};
7
8use crate::content;
9use crate::error::HaystackError;
10use crate::state::AppState;
11
12pub async fn handle_status(
16 req: HttpRequest,
17 state: web::Data<AppState>,
18) -> Result<HttpResponse, HaystackError> {
19 let accept = req
20 .headers()
21 .get("Accept")
22 .and_then(|v| v.to_str().ok())
23 .unwrap_or("");
24
25 let status = state.federation.status();
26
27 let grid = if status.is_empty() {
28 HGrid::from_parts(
29 HDict::new(),
30 vec![HCol::new("name"), HCol::new("entityCount")],
31 vec![],
32 )
33 } else {
34 let rows: Vec<HDict> = status
35 .into_iter()
36 .map(|(name, count)| {
37 let mut row = HDict::new();
38 row.set("name", Kind::Str(name));
39 row.set("entityCount", Kind::Number(Number::unitless(count as f64)));
40 row
41 })
42 .collect();
43 HGrid::from_parts(
44 HDict::new(),
45 vec![HCol::new("name"), HCol::new("entityCount")],
46 rows,
47 )
48 };
49
50 let (encoded, ct) = content::encode_response_grid(&grid, accept)
51 .map_err(|e| HaystackError::internal(format!("encoding error: {e}")))?;
52
53 Ok(HttpResponse::Ok().content_type(ct).body(encoded))
54}
55
56pub async fn handle_sync(
61 req: HttpRequest,
62 state: web::Data<AppState>,
63) -> Result<HttpResponse, HaystackError> {
64 let accept = req
65 .headers()
66 .get("Accept")
67 .and_then(|v| v.to_str().ok())
68 .unwrap_or("");
69
70 let results = state.federation.sync_all().await;
71
72 let rows: Vec<HDict> = results
73 .into_iter()
74 .map(|(name, result)| {
75 let mut row = HDict::new();
76 row.set("name", Kind::Str(name));
77 match result {
78 Ok(count) => {
79 row.set("result", Kind::Str(format!("{count} entities")));
80 row.set("ok", Kind::Bool(true));
81 }
82 Err(err) => {
83 row.set("result", Kind::Str(err));
84 row.set("ok", Kind::Bool(false));
85 }
86 }
87 row
88 })
89 .collect();
90
91 let grid = HGrid::from_parts(
92 HDict::new(),
93 vec![HCol::new("name"), HCol::new("result"), HCol::new("ok")],
94 rows,
95 );
96
97 let (encoded, ct) = content::encode_response_grid(&grid, accept)
98 .map_err(|e| HaystackError::internal(format!("encoding error: {e}")))?;
99
100 Ok(HttpResponse::Ok().content_type(ct).body(encoded))
101}