92 lines
3.3 KiB
Rust
92 lines
3.3 KiB
Rust
use std::str::FromStr;
|
|
|
|
use warp::{http::HeaderValue, hyper::Uri, path::Tail, reply::Response, Filter, Rejection, Reply};
|
|
|
|
use super::servek::{Server, ServerError};
|
|
use rust_embed::RustEmbed;
|
|
|
|
#[derive(RustEmbed)]
|
|
#[folder = "static"]
|
|
struct StaticData;
|
|
|
|
impl Server {
|
|
pub(super) async fn html(
|
|
&self,
|
|
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
|
Self::index()
|
|
.or(self.profile().await)
|
|
.or(self.create_profile().await.or(Server::static_files()))
|
|
}
|
|
|
|
fn index() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
|
warp::get().and(warp::path::end().map(move || {
|
|
warp::reply::html(include_str!("../../templates/html/index.html").to_owned())
|
|
}))
|
|
}
|
|
|
|
fn with_server(
|
|
srv: Server,
|
|
) -> impl Filter<Extract = (Server,), Error = std::convert::Infallible> + Clone {
|
|
warp::any().map(move || srv.clone())
|
|
}
|
|
|
|
async fn profile(&self) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
|
warp::get().and(
|
|
warp::path!("@" / String)
|
|
.and(Self::with_server(self.clone()))
|
|
.and_then(|username: String, srv: Server| async move {
|
|
srv.hb
|
|
.render(
|
|
"profile",
|
|
&serde_json::json!(srv
|
|
.profiler
|
|
.profile(username)
|
|
.await
|
|
.map_err(|e| ServerError::from(e))?),
|
|
)
|
|
.map(|html| warp::reply::html(html))
|
|
.map_err(|e| ServerError::from(e).reject_self())
|
|
}),
|
|
)
|
|
}
|
|
|
|
async fn create_profile(&self) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
|
warp::post().and(
|
|
warp::path!("@" / String)
|
|
.and(Self::with_server(self.clone()))
|
|
.and_then(|username: String, srv: Server| async move {
|
|
let user = srv
|
|
.profiler
|
|
.create_user(username, None)
|
|
.await
|
|
.map_err(|e| ServerError::from(e));
|
|
match user {
|
|
Ok(u) => Ok(warp::redirect(
|
|
Uri::from_str(format!("/@/{}", u.username).as_str()).unwrap(),
|
|
)),
|
|
Err(e) => Err(e.reject_self()),
|
|
}
|
|
}),
|
|
)
|
|
}
|
|
|
|
fn static_files() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
|
warp::get().and(warp::path("static").and(warp::path::tail()).and_then(
|
|
|path: Tail| async move {
|
|
let asset = match StaticData::get(path.as_str()) {
|
|
Some(a) => a,
|
|
None => return Err(ServerError::NotFound.reject_self()),
|
|
};
|
|
let mime = mime_guess::from_path(path.as_str()).first_or_octet_stream();
|
|
|
|
let mut res = Response::new(asset.data.into());
|
|
res.headers_mut().insert(
|
|
"Content-Type",
|
|
HeaderValue::from_str(mime.as_ref()).unwrap(),
|
|
);
|
|
Ok(res)
|
|
},
|
|
))
|
|
}
|
|
}
|