2023-05-11 17:34:05 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-05-12 12:51:10 +00:00
|
|
|
use std::collections::HashMap;
|
2023-05-11 17:34:05 +00:00
|
|
|
use std::error::Error;
|
|
|
|
use std::sync;
|
2023-05-11 12:19:36 +00:00
|
|
|
use warp::Filter;
|
|
|
|
|
2023-05-11 17:34:05 +00:00
|
|
|
use crate::domain;
|
|
|
|
|
|
|
|
pub mod http_tpl;
|
|
|
|
|
2023-05-11 12:19:36 +00:00
|
|
|
/*
|
2023-05-12 12:51:10 +00:00
|
|
|
* POST /domain/config (domain, config, secret, init?) -> token?
|
2023-05-11 12:19:36 +00:00
|
|
|
* GET /domain/config (domain) -> config
|
|
|
|
* GET /domains
|
|
|
|
*/
|
|
|
|
|
2023-05-11 17:34:05 +00:00
|
|
|
type Handlebars<'a> = sync::Arc<handlebars::Handlebars<'a>>;
|
|
|
|
|
2023-05-12 12:51:10 +00:00
|
|
|
struct RenderContext<'a> {
|
|
|
|
handlebars: Handlebars<'a>,
|
|
|
|
query_args: HashMap<String, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO make this use an io::Write, rather than warp::Reply
|
|
|
|
fn render<'a, T>(handlebars: Handlebars<'a>, name: &'a str, value: T) -> impl warp::Reply
|
2023-05-11 17:34:05 +00:00
|
|
|
where
|
|
|
|
T: Serialize,
|
|
|
|
{
|
|
|
|
// TODO deal with 404
|
2023-05-12 12:51:10 +00:00
|
|
|
let render = handlebars
|
|
|
|
.render(name, &value)
|
2023-05-11 17:34:05 +00:00
|
|
|
.unwrap_or_else(|err| err.to_string());
|
|
|
|
|
|
|
|
let content_type = mime_guess::from_path(name)
|
|
|
|
.first_or_octet_stream()
|
|
|
|
.to_string();
|
|
|
|
|
2023-05-12 12:51:10 +00:00
|
|
|
let reply = warp::reply::html(render);
|
|
|
|
|
|
|
|
warp::reply::with_header(reply, "Content-Type", content_type)
|
2023-05-11 17:34:05 +00:00
|
|
|
}
|
|
|
|
|
2023-05-12 12:51:10 +00:00
|
|
|
fn render_page<'a, T>(render_ctx: RenderContext<'a>, name: String, data: T) -> impl warp::Reply
|
|
|
|
where
|
|
|
|
T: Serialize,
|
|
|
|
{
|
|
|
|
#[derive(Serialize)]
|
|
|
|
struct Presenter<T> {
|
|
|
|
page_name: String,
|
|
|
|
query_args: HashMap<String, String>,
|
|
|
|
data: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
let presenter = Presenter {
|
|
|
|
page_name: name,
|
|
|
|
query_args: render_ctx.query_args,
|
|
|
|
data,
|
|
|
|
};
|
|
|
|
|
|
|
|
render(render_ctx.handlebars, "/base.html", presenter)
|
2023-05-11 17:34:05 +00:00
|
|
|
}
|
|
|
|
|
2023-05-11 12:19:36 +00:00
|
|
|
pub fn new(
|
2023-05-11 17:34:05 +00:00
|
|
|
_manager: impl domain::manager::Manager,
|
|
|
|
) -> Result<
|
|
|
|
impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone,
|
|
|
|
Box<dyn Error>,
|
|
|
|
> {
|
|
|
|
let hbs = sync::Arc::new(self::http_tpl::get()?);
|
2023-05-12 12:51:10 +00:00
|
|
|
let with_render_ctx = warp::any()
|
|
|
|
.and(warp::query::<HashMap<String, String>>())
|
|
|
|
.map(move |query_args: HashMap<String, String>| RenderContext {
|
|
|
|
handlebars: hbs.clone(),
|
|
|
|
query_args,
|
|
|
|
});
|
2023-05-11 17:34:05 +00:00
|
|
|
|
|
|
|
let static_dir = warp::get()
|
2023-05-12 12:51:10 +00:00
|
|
|
.and(with_render_ctx.clone())
|
2023-05-11 17:34:05 +00:00
|
|
|
.and(warp::path("static"))
|
|
|
|
.and(warp::path::full())
|
2023-05-12 12:51:10 +00:00
|
|
|
.map(
|
|
|
|
|render_ctx: RenderContext<'_>, full: warp::path::FullPath| {
|
|
|
|
render(render_ctx.handlebars, full.as_str(), ())
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
let index = warp::get()
|
|
|
|
.and(with_render_ctx.clone())
|
|
|
|
.and(warp::path::end())
|
|
|
|
.map(|render_ctx: RenderContext<'_>| {
|
|
|
|
render_page(render_ctx, String::from("/index.html"), ())
|
|
|
|
});
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct DomainGetNewRequest {
|
|
|
|
domain: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
let domain_get = warp::get()
|
|
|
|
.and(with_render_ctx.clone())
|
|
|
|
.and(warp::path("domain.html"))
|
|
|
|
.and(warp::query::<DomainGetNewRequest>())
|
|
|
|
.map(|render_ctx: RenderContext<'_>, req: DomainGetNewRequest| {
|
|
|
|
#[derive(Serialize)]
|
|
|
|
struct DomainGetNewResponse {
|
|
|
|
domain: String,
|
|
|
|
}
|
2023-05-11 17:34:05 +00:00
|
|
|
|
2023-05-12 12:51:10 +00:00
|
|
|
render_page(
|
|
|
|
render_ctx,
|
|
|
|
String::from("/domain_get_new.html"),
|
|
|
|
DomainGetNewResponse { domain: req.domain },
|
|
|
|
)
|
|
|
|
});
|
2023-05-11 17:34:05 +00:00
|
|
|
|
2023-05-12 12:51:10 +00:00
|
|
|
Ok(static_dir.or(index).or(domain_get))
|
2023-05-11 12:19:36 +00:00
|
|
|
}
|