Clean up architecture

This commit is contained in:
2026-03-25 17:53:44 +01:00
parent 17ddf9071e
commit d4872a1a04
31 changed files with 1490 additions and 1104 deletions

View File

@@ -78,10 +78,5 @@ pub fn list_library_references_recursive(
state: State<AppState>,
library_id: LibraryId,
) -> Result<Vec<ReferenceSummary>, String> {
let result = state.with_repo_read(|b| b.list_library_references_recursive(library_id));
match &result {
Ok(refs) => eprintln!("[brittle] list_library_references_recursive({library_id}): {} refs", refs.len()),
Err(e) => eprintln!("[brittle] list_library_references_recursive({library_id}): ERROR: {e}"),
}
result
state.with_repo_read(|b| b.list_library_references_recursive(library_id))
}

View File

@@ -50,11 +50,11 @@ pub fn handle<R: Runtime>(app: &AppHandle<R>, req: &Request<Vec<u8>>) -> Respons
// ── Route handlers ────────────────────────────────────────────────────────────
fn serve_viewer(ref_id: &str) -> Response<Vec<u8>> {
// Substitute the ref_id into the HTML template so the viewer knows which PDF to load.
let html = String::from_utf8_lossy(VIEWER_HTML)
.replace("ref_id=\"\"", &format!("ref_id=\"{}\"", ref_id));
response_ok(html.into_bytes(), "text/html; charset=utf-8")
fn serve_viewer(_ref_id: &str) -> Response<Vec<u8>> {
// The viewer reads `ref_id` from its own URL query string via JavaScript
// (`new URLSearchParams(location.search).get("ref_id")`), so no substitution
// into the HTML template is needed.
response_ok(VIEWER_HTML.to_vec(), "text/html; charset=utf-8")
}
fn serve_pdfjs_file(rel_path: &str) -> Response<Vec<u8>> {
@@ -148,7 +148,6 @@ fn response_500(msg: &str) -> Response<Vec<u8>> {
// ── Pure routing logic (unit-testable) ───────────────────────────────────────
pub mod routing {
use std::path::Path;
#[derive(Debug, PartialEq)]
pub enum Route {
@@ -185,23 +184,6 @@ pub mod routing {
.to_owned()
}
/// Return the appropriate MIME type for a file path based on its extension.
pub fn mime_for_path(path: &Path) -> &'static str {
match path.extension().and_then(|e| e.to_str()) {
Some("js") => "application/javascript; charset=utf-8",
Some("mjs") => "application/javascript; charset=utf-8",
Some("css") => "text/css; charset=utf-8",
Some("html") => "text/html; charset=utf-8",
Some("pdf") => "application/pdf",
Some("woff2") => "font/woff2",
Some("woff") => "font/woff",
Some("png") => "image/png",
Some("jpg") | Some("jpeg") => "image/jpeg",
Some("svg") => "image/svg+xml",
Some("map") => "application/json",
_ => "application/octet-stream",
}
}
#[cfg(test)]
mod tests {
@@ -276,24 +258,6 @@ pub mod routing {
assert_eq!(extract_ref_id(Some("foo=bar")), "");
}
#[test]
fn mime_for_js_files() {
assert!(mime_for_path(Path::new("pdf.min.js")).contains("javascript"));
}
#[test]
fn mime_for_css_files() {
assert!(mime_for_path(Path::new("viewer.css")).contains("css"));
}
#[test]
fn mime_for_unknown_extension() {
assert_eq!(
mime_for_path(Path::new("data.bin")),
"application/octet-stream"
);
}
#[test]
fn path_traversal_rel_path_contains_dotdot() {
// The handler rejects rel_paths containing ".."; verify the routing