use std::str::FromStr; use warp::{hyper::Uri, Filter, Rejection, Reply}; use super::servek::{Server, ServerError}; impl Server { pub(super) async fn html( &self, ) -> impl Filter + Clone { Self::index() .or(self.profile().await) .or(self.create_profile().await) } fn index() -> impl Filter + 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 + Clone { warp::any().map(move || srv.clone()) } async fn profile(&self) -> impl Filter + 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 + 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()), } }), ) } }