checkpoint
This commit is contained in:
Generated
+1
@@ -1133,6 +1133,7 @@ name = "fleen"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
|
"bytes",
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui_ltreeview",
|
"egui_ltreeview",
|
||||||
"markdown",
|
"markdown",
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ markdown = "1.0.0"
|
|||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
axum = "0.8.4"
|
axum = "0.8.4"
|
||||||
tokio = { version = "1.47.1", features = ["full"] }
|
tokio = { version = "1.47.1", features = ["full"] }
|
||||||
|
bytes = "1.10.1"
|
||||||
|
|||||||
+26
-7
@@ -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
|
/// 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> {
|
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()) {
|
if skipped_path(source.clone()) {
|
||||||
return Ok(RenderOutput::NoOutput)
|
// Skipped path, nothing
|
||||||
}
|
Ok(RenderOutput::NoOutput)
|
||||||
if root.join(source.clone()).is_dir() {
|
} else if root.join(source.clone()).is_dir() {
|
||||||
return Ok(RenderOutput::Dir(source))
|
// Dir, which matters for producing files
|
||||||
}
|
Ok(RenderOutput::Dir(source))
|
||||||
match source.extension().map(|o| o.to_str().unwrap()) {
|
} 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),
|
Some("md") => render_as_markdown(source.clone(), root),
|
||||||
_ => Ok(RenderOutput::RawFile(source))
|
// 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() {
|
fn test_dir() {
|
||||||
assert!(matches!(render_file("dir"), RenderOutput::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::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use axum::body::Body;
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
|
use axum::http::Uri;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use axum::routing::get;
|
use axum::routing::get;
|
||||||
@@ -9,7 +12,13 @@ use crate::renderer::{default_path, render, RenderOutput};
|
|||||||
pub async fn start_server(root: PathBuf) {
|
pub async fn start_server(root: PathBuf) {
|
||||||
let state = Arc::new(root);
|
let state = Arc::new(root);
|
||||||
let app = Router::new()
|
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);
|
.with_state(state);
|
||||||
|
|
||||||
// run our app with hyper, listening globally on port 3000
|
// 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();
|
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 {
|
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());
|
let render = render(path.into(), root.as_ref());
|
||||||
|
|
||||||
match render {
|
match render {
|
||||||
Ok(RenderOutput::Rendered(file, content)) |
|
Ok(RenderOutput::Rendered(_, content)) |
|
||||||
Ok(RenderOutput::Hidden(file, content)) => {
|
Ok(RenderOutput::Hidden(_, content)) => {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(200)
|
.status(200)
|
||||||
.header("Content-Type", "text/html")
|
.body(Body::from(content)).unwrap()
|
||||||
.body(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::NoOutput) |
|
||||||
Ok(RenderOutput::Dir(_)) => {
|
Ok(RenderOutput::Dir(_)) => {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(404)
|
.status(404)
|
||||||
.body(String::from("Not Found")).unwrap()
|
.body(Body::from(include_str!("../templates/404.html"))).unwrap()
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(500)
|
.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