forked from
microcosm.blue/microcosm-rs
Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm
1use askama::Template;
2use axum::http::StatusCode;
3use axum::response::{Html, IntoResponse, Json, Response};
4use axum_extra::TypedHeader;
5use headers_accept::Accept;
6use mediatype::names::{APPLICATION, HTML, JSON, TEXT};
7use mediatype::MediaType;
8use serde::Serialize;
9
10const TEXT_HTML: MediaType = MediaType::new(TEXT, HTML);
11const APPLICATION_JSON: MediaType = MediaType::new(APPLICATION, JSON);
12const AVAILABLE: &[MediaType] = &[APPLICATION_JSON, TEXT_HTML];
13
14pub type ExtractAccept = Option<TypedHeader<Accept>>;
15
16pub fn acceptable<T: Serialize + Template>(accept: ExtractAccept, thing: T) -> Response {
17 if let Some(accepting) = accept {
18 if accepting.negotiate(AVAILABLE) == Some(&TEXT_HTML) {
19 match thing.render() {
20 Ok(content) => return Html(content).into_response(),
21 Err(e) => {
22 eprintln!("template rendering failed: {e:?}");
23 return StatusCode::INTERNAL_SERVER_ERROR.into_response();
24 }
25 }
26 }
27 }
28 Json(thing).into_response()
29}