checkpoint

This commit is contained in:
2025-09-01 19:15:30 -05:00
parent 434c793edf
commit e34b4b321e
5 changed files with 60 additions and 23 deletions
Generated
+1
View File
@@ -1133,6 +1133,7 @@ name = "fleen"
version = "0.1.0"
dependencies = [
"axum",
"bytes",
"eframe",
"egui_ltreeview",
"markdown",
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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()
}
}
}
+9
View File
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Not found</title>
</head>
<body>
Not found
</body>
</html>