#![warn(unused_extern_crates)] #![allow(clippy::style)] use serde::{Deserialize, Serialize}; use std::path::PathBuf; use warp::{Filter, filters::path::FullPath}; #[path = "lib/curl.rs"] mod curl; #[path = "lib/html.rs"] mod html; #[path = "lib/markdowner.rs"] mod markdowner; #[path = "lib/sidebar.rs"] mod sidebar; use crate::{ curl::curl_response, html::html_response, markdowner::MarkdownModule, sidebar::sidebar_content, }; #[derive(Serialize, Deserialize)] struct WebQuery { width: Option, } fn router(request_path: PathBuf) -> PathBuf { std::env::current_dir() .expect("unable to determine current directory") .join("serve") .join(request_path) } fn renderer(path: FullPath, user_agent: String, query: WebQuery) -> Box { println!("{:?} requested by {}", path, user_agent); let request_path: PathBuf = path.as_str().strip_prefix("/").unwrap_or_default().into(); let target_path = router(request_path); if !target_path.exists() || target_path.is_file() { return Box::new(warp::redirect( warp::http::uri::Builder::new() .authority(".") .build() .unwrap(), )); } println!("serving path: {:?}", target_path); let page_contents = markdowner::get_markdown_modules(&target_path); let sidebar_dir = PathBuf::from("assets/sidebar/"); let sidebar_contents = sidebar_content(&router(sidebar_dir)); let response = if user_agent.starts_with("curl/") { curl_response(page_contents, sidebar_contents, query.width) } else { html_response( page_contents, sidebar_contents, target_path .file_stem() .unwrap_or_default() .to_str() .unwrap_or_default() .to_owned(), ) }; response } #[tokio::main] async fn main() { println!("Hello, world!"); let assets = warp::path("assets").and(warp::fs::dir("./serve/assets/")); let favicon = warp::path("favicon.ico").and(warp::fs::file("./serve/favicon.ico")); let markdowns = warp::any() //path::end() .and(warp::path::full()) .and(warp::header("user-agent")) .and(warp::query::()) .map(|path: FullPath, agent: String, query: WebQuery| renderer(path, agent, query)); let routes = favicon.or(assets).or(markdowns); warp::serve(routes).run(([0, 0, 0, 0], 3030)).await; }