Skip to main content

chronicle/web/
mod.rs

1mod api;
2mod assets;
3
4use crate::error::{ChronicleError, Result};
5use crate::git::CliOps;
6
7pub fn serve(git_ops: CliOps, port: u16, open_browser: bool) -> Result<()> {
8    let addr = format!("0.0.0.0:{port}");
9    let server = tiny_http::Server::http(&addr).map_err(|e| ChronicleError::Config {
10        message: format!("failed to start web server on {addr}: {e}"),
11        location: snafu::Location::default(),
12    })?;
13
14    println!("Chronicle web viewer: http://localhost:{port}");
15    if open_browser {
16        open::that(format!("http://localhost:{port}")).ok();
17    }
18
19    for request in server.incoming_requests() {
20        let url = request.url().to_string();
21        let result = if url.starts_with("/api/") {
22            api::handle(&git_ops, &url)
23        } else {
24            Ok(assets::handle(&url))
25        };
26
27        match result {
28            Ok(response) => {
29                request.respond(response).ok();
30            }
31            Err(e) => {
32                let body = serde_json::json!({ "error": e.to_string() }).to_string();
33                let response = tiny_http::Response::from_string(body)
34                    .with_header(
35                        tiny_http::Header::from_bytes(
36                            &b"Content-Type"[..],
37                            &b"application/json"[..],
38                        )
39                        .unwrap(),
40                    )
41                    .with_status_code(500);
42                request.respond(response).ok();
43            }
44        }
45    }
46
47    Ok(())
48}