use axum::Json;
use axum::http::header;
use axum::response::{IntoResponse, Response};
use serde::Serialize;
use std::fmt::Write;
use std::time::Duration;
use tibba_error::Error;
type Result<T> = std::result::Result<T, Error>;
pub type JsonResult<T> = Result<Json<T>>;
const S_MAX_AGE_LIMIT_SECS: u64 = 3600;
pub struct CacheJson<T> {
pub duration: Duration,
pub data: T,
}
pub type CacheJsonResult<T> = Result<CacheJson<T>>;
impl<T> From<(Duration, T)> for CacheJson<T> {
fn from(value: (Duration, T)) -> Self {
Self {
duration: value.0,
data: value.1,
}
}
}
impl<T> IntoResponse for CacheJson<T>
where
T: Serialize,
{
fn into_response(self) -> Response {
let secs = self.duration.as_secs();
let mut cache_control_value = String::with_capacity(64);
let _ = write!(&mut cache_control_value, "public, max-age={secs}");
if secs > S_MAX_AGE_LIMIT_SECS {
let _ = write!(
&mut cache_control_value,
", s-maxage={S_MAX_AGE_LIMIT_SECS}"
);
}
(
[(header::CACHE_CONTROL, cache_control_value)],
Json(self.data),
)
.into_response()
}
}