use tide::{
http::{
headers::{HeaderName, HeaderValues, ToHeaderValues},
mime,
},
Redirect, Response,
};
pub trait RedirectStrategy: Send + Sync {
fn redirect(&self) -> Response;
}
#[derive(Debug)]
pub struct HttpRedirect {
path: String,
}
impl HttpRedirect {
pub fn new(path: impl AsRef<str>) -> Self {
Self {
path: path.as_ref().to_string(),
}
}
}
impl RedirectStrategy for HttpRedirect {
fn redirect(&self) -> Response {
Redirect::new(self.path.clone()).into()
}
}
#[derive(Debug)]
pub struct ClientSideRefresh {
body: String,
headers: Vec<(HeaderName, HeaderValues)>,
}
impl ClientSideRefresh {
pub fn from_path(path: impl AsRef<str>) -> Self {
let body = format!("<!DOCTYPE html><html><head><meta http-equiv=\"refresh\" content=\"0;URL='{0}'\" /></head><body></body></html>", path.as_ref());
ClientSideRefresh::from_body(body)
}
pub fn from_body(body: impl AsRef<str>) -> Self {
Self {
body: body.as_ref().to_string(),
headers: Vec::new(),
}
}
pub fn with_header(mut self, name: impl Into<HeaderName>, values: impl ToHeaderValues) -> Self {
self.headers.push((
name.into(),
values
.to_header_values()
.expect("Invalid header value.")
.collect(),
));
self
}
}
impl RedirectStrategy for ClientSideRefresh {
fn redirect(&self) -> Response {
let mut res = Response::builder(200)
.body(self.body.clone())
.content_type(mime::HTML);
for (name, values) in self.headers.iter() {
res = res.header(name, values);
}
res.build()
}
}