checkpoint
This commit is contained in:
Generated
+1
@@ -1133,6 +1133,7 @@ name = "fleen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"bytes",
|
||||
"eframe",
|
||||
"egui_ltreeview",
|
||||
"markdown",
|
||||
|
||||
@@ -13,3 +13,4 @@ markdown = "1.0.0"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
axum = "0.8.4"
|
||||
tokio = { version = "1.47.1", features = ["full"] }
|
||||
bytes = "1.10.1"
|
||||
|
||||
+27
-8
@@ -71,15 +71,28 @@ pub fn default_path(root: &PathBuf) -> PathBuf {
|
||||
|
||||
/// Take a source file path (relative to the root) and the root path, and return a RenderOutput for it
|
||||
pub fn render(source: PathBuf, root: &PathBuf) -> Result<RenderOutput, RenderError> {
|
||||
let extension = source.extension().map(|o| o.to_str().unwrap());
|
||||
if skipped_path(source.clone()) {
|
||||
return Ok(RenderOutput::NoOutput)
|
||||
}
|
||||
if root.join(source.clone()).is_dir() {
|
||||
return Ok(RenderOutput::Dir(source))
|
||||
}
|
||||
match source.extension().map(|o| o.to_str().unwrap()) {
|
||||
Some("md") => render_as_markdown(source.clone(), root),
|
||||
_ => Ok(RenderOutput::RawFile(source))
|
||||
// Skipped path, nothing
|
||||
Ok(RenderOutput::NoOutput)
|
||||
} else if root.join(source.clone()).is_dir() {
|
||||
// Dir, which matters for producing files
|
||||
Ok(RenderOutput::Dir(source))
|
||||
} else if let Ok(true) = fs::exists(root.join(source.clone())) {
|
||||
match extension {
|
||||
// Asked for a markdown file, render it
|
||||
// TODO this is a little silly for the server, this should properly be NoOutput but that's a big change
|
||||
Some("md") => render_as_markdown(source.clone(), root),
|
||||
// Not a markdown file, but it exists, return it raw
|
||||
_ => Ok(RenderOutput::RawFile(root.join(source)))
|
||||
}
|
||||
} else if matches!(extension, Some("html")) &&
|
||||
let Ok(true) = fs::exists(root.join(source.with_extension("md"))) {
|
||||
// We asked for an html file which doesn't exist but a corresponding md file does, render it
|
||||
render_as_markdown(source.with_extension("md"), root)
|
||||
} else {
|
||||
// Asked for something which doesn't exist and it's not the md -> html case, 404:
|
||||
Ok(RenderOutput::NoOutput)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,4 +221,10 @@ mod tests {
|
||||
fn test_dir() {
|
||||
assert!(matches!(render_file("dir"), RenderOutput::Dir(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ask_for_html() {
|
||||
let contents = render_file("index.html");
|
||||
assert!(matches!(contents, RenderOutput::Rendered(_, _))) // We asked for the html file which doesn't exist but the md does
|
||||
}
|
||||
}
|
||||
+22
-15
@@ -1,6 +1,9 @@
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use axum::body::Body;
|
||||
use axum::extract::State;
|
||||
use axum::http::Uri;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use axum::Router;
|
||||
use axum::routing::get;
|
||||
@@ -9,7 +12,13 @@ use crate::renderer::{default_path, render, RenderOutput};
|
||||
pub async fn start_server(root: PathBuf) {
|
||||
let state = Arc::new(root);
|
||||
let app = Router::new()
|
||||
.route("/", get(handler))
|
||||
.route("/", get(|State(root): State<Arc<PathBuf>>| async {
|
||||
let path = default_path(&root);
|
||||
serve_path(String::from(path.to_str().unwrap()), root)
|
||||
}))
|
||||
.route("/{*path}", get(|State(root): State<Arc<PathBuf>>, uri: Uri| async move {
|
||||
serve_path(String::from(uri.path()), root)
|
||||
}))
|
||||
.with_state(state);
|
||||
|
||||
// run our app with hyper, listening globally on port 3000
|
||||
@@ -17,34 +26,32 @@ pub async fn start_server(root: PathBuf) {
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handler(
|
||||
State(root): State<Arc<PathBuf>>,
|
||||
) -> impl IntoResponse {
|
||||
let path = default_path(&root);
|
||||
serve_path(String::from(path.to_str().unwrap()), root)
|
||||
}
|
||||
|
||||
fn serve_path(path: String, root: impl AsRef<PathBuf>) -> impl IntoResponse {
|
||||
let path = path.strip_prefix("/").unwrap_or(path.as_str());
|
||||
let render = render(path.into(), root.as_ref());
|
||||
|
||||
match render {
|
||||
Ok(RenderOutput::Rendered(file, content)) |
|
||||
Ok(RenderOutput::Hidden(file, content)) => {
|
||||
Ok(RenderOutput::Rendered(_, content)) |
|
||||
Ok(RenderOutput::Hidden(_, content)) => {
|
||||
Response::builder()
|
||||
.status(200)
|
||||
.header("Content-Type", "text/html")
|
||||
.body(content).unwrap()
|
||||
.body(Body::from(content)).unwrap()
|
||||
}
|
||||
Ok(RenderOutput::RawFile(file)) => {
|
||||
Response::builder()
|
||||
.status(200)
|
||||
.body(Body::from(fs::read(file).unwrap_or(vec![]))).unwrap()
|
||||
}
|
||||
Ok(RenderOutput::RawFile(file)) => { todo!() }
|
||||
Ok(RenderOutput::NoOutput) |
|
||||
Ok(RenderOutput::Dir(_)) => {
|
||||
Response::builder()
|
||||
.status(404)
|
||||
.body(String::from("Not Found")).unwrap()
|
||||
.body(Body::from(include_str!("../templates/404.html"))).unwrap()
|
||||
}
|
||||
Err(err) => {
|
||||
Response::builder()
|
||||
.status(500)
|
||||
.body(format!("{}", err)).unwrap()
|
||||
.body(Body::from(format!("{}", err))).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Not found</title>
|
||||
</head>
|
||||
<body>
|
||||
Not found
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user