Skip to main content

haystack_server/ops/
formats.rs

1//! The `formats` op — list supported MIME types.
2
3use actix_web::{HttpRequest, HttpResponse, web};
4
5use haystack_core::data::{HCol, HDict, HGrid};
6use haystack_core::kinds::Kind;
7
8use crate::content;
9use crate::state::AppState;
10
11/// GET /api/formats — returns a grid listing supported MIME formats.
12pub async fn handle(req: HttpRequest, _state: web::Data<AppState>) -> HttpResponse {
13    let accept = req
14        .headers()
15        .get("Accept")
16        .and_then(|v| v.to_str().ok())
17        .unwrap_or("");
18
19    let formats = vec![
20        ("text/zinc", "Zinc"),
21        ("application/json", "JSON (Haystack 4)"),
22        ("text/trio", "Trio"),
23        ("application/json;v=3", "JSON (Haystack 3)"),
24    ];
25
26    let cols = vec![HCol::new("mime"), HCol::new("receive"), HCol::new("send")];
27    let rows: Vec<HDict> = formats
28        .into_iter()
29        .map(|(mime, _label)| {
30            let mut row = HDict::new();
31            row.set("mime", Kind::Str(mime.to_string()));
32            row.set("receive", Kind::Marker);
33            row.set("send", Kind::Marker);
34            row
35        })
36        .collect();
37
38    let grid = HGrid::from_parts(HDict::new(), cols, rows);
39    match content::encode_response_grid(&grid, accept) {
40        Ok((body, ct)) => HttpResponse::Ok().content_type(ct).body(body),
41        Err(e) => {
42            log::error!("Failed to encode formats grid: {e}");
43            HttpResponse::InternalServerError().body("encoding error")
44        }
45    }
46}