use rocket::http::Status; use rocket::response::Responder; use rocket::{Request, Response, response}; use std::ops::{FromResidual, Try}; #[derive(Debug)] pub struct CachedOption(Option<(rocket::http::ContentType, Vec)>); impl CachedOption { fn into_option(self) -> Option<(rocket::http::ContentType, Vec)> { self.0 } } impl From)>> for CachedOption { fn from(value: Option<(rocket::http::ContentType, Vec)>) -> Self { Self(value) } } impl FromResidual> for CachedOption { fn from_residual(_: std::option::Option) -> Self { Self(None) } } impl FromResidual for CachedOption { fn from_residual(residual: CachedOption) -> Self { residual } } impl Try for CachedOption { type Output = Option<(rocket::http::ContentType, Vec)>; type Residual = Self; fn from_output(output: Self::Output) -> Self { Self(output) } fn branch(self) -> std::ops::ControlFlow { match self.0 { Some((ct, bytes)) => std::ops::ControlFlow::Break(Self(Some((ct, bytes)))), None => std::ops::ControlFlow::Continue(None), } } } impl<'r> Responder<'r, 'static> for CachedOption { fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { let option = self.into_option(); if let Some((ct, bytes)) = option { Response::build() .header(ct) .header(rocket::http::Header::new( "Cache-Control", "max-age=31536000", )) .sized_body(bytes.len(), std::io::Cursor::new(bytes)) .ok() } else { Err(Status::InternalServerError) } } }