66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
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<u8>)>);
|
|
|
|
impl CachedOption {
|
|
fn into_option(self) -> Option<(rocket::http::ContentType, Vec<u8>)> {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
impl From<Option<(rocket::http::ContentType, Vec<u8>)>> for CachedOption {
|
|
fn from(value: Option<(rocket::http::ContentType, Vec<u8>)>) -> Self {
|
|
Self(value)
|
|
}
|
|
}
|
|
|
|
impl FromResidual<std::option::Option<std::convert::Infallible>> for CachedOption {
|
|
fn from_residual(_: std::option::Option<std::convert::Infallible>) -> Self {
|
|
Self(None)
|
|
}
|
|
}
|
|
|
|
impl FromResidual<CachedOption> for CachedOption {
|
|
fn from_residual(residual: CachedOption) -> Self {
|
|
residual
|
|
}
|
|
}
|
|
|
|
impl Try for CachedOption {
|
|
type Output = Option<(rocket::http::ContentType, Vec<u8>)>;
|
|
type Residual = Self;
|
|
|
|
fn from_output(output: Self::Output) -> Self {
|
|
Self(output)
|
|
}
|
|
|
|
fn branch(self) -> std::ops::ControlFlow<Self::Residual, Self::Output> {
|
|
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)
|
|
}
|
|
}
|
|
}
|