offline-web/exp1/src/serve.rs

73 lines
2.3 KiB
Rust
Raw Normal View History

2025-04-02 18:23:03 -04:00
use std::{collections::HashMap, sync::Arc};
2025-03-29 20:32:25 -04:00
use axum::{extract::Path, http, response::{Html, IntoResponse}, routing::get, Json, Router};
2025-03-28 17:46:09 -04:00
2025-05-02 16:32:39 -04:00
use offline_web_model::{Graph, Reference};
2025-03-30 15:02:46 -04:00
2025-04-12 15:53:40 -04:00
// TODO(jeremy): Allow this to autoexpand the content_addresses?
2025-04-02 18:23:03 -04:00
async fn all_references(root_ref: Arc<Reference>) -> Json<Arc<Reference>> {
Json(root_ref)
2025-03-30 15:02:46 -04:00
}
2025-04-02 18:23:03 -04:00
async fn ref_path(refs: Arc<HashMap<String, Arc<Reference>>>, Path(path): Path<String>) -> Json<Arc<Reference>> {
let path = format!("/item/{}", path);
match refs.get(&path) {
Some(r) => Json(r.clone()),
None => todo!("Return a 404?"),
}
2025-03-30 15:02:46 -04:00
}
2025-05-21 19:23:13 -04:00
async fn object_path(objects: Arc<HashMap<String, Vec<u8>>>, Path(addr): Path<String>) -> Vec<u8> {
dbg!(&addr);
match objects.get(&addr) {
2025-05-02 16:32:39 -04:00
Some(o) => o.clone(),
2025-04-02 18:23:03 -04:00
None => todo!("Return a 404?"),
}
2025-03-29 20:32:25 -04:00
}
2025-03-30 21:18:08 -04:00
async fn get_client_js() -> impl IntoResponse {
(
[(http::header::CONTENT_TYPE, "application/javascript")],
include_str!("../static/client.js"),
)
}
2025-05-02 16:32:39 -04:00
pub fn endpoints(graph: Graph) -> Router {
2025-03-30 15:02:46 -04:00
Router::new().nest(
"/api/v1",
Router::new().nest(
"/ref",
Router::new()
2025-04-02 18:23:03 -04:00
.route("/all/username", get({
2025-05-02 16:32:39 -04:00
let state = graph.root.clone();
2025-04-02 18:23:03 -04:00
move || all_references(state)
}))
.route("/item/{*path}", get({
2025-05-02 16:32:39 -04:00
let refs = graph.refs.clone();
2025-04-02 18:23:03 -04:00
move |path| ref_path(refs, path)
}))
2025-03-30 15:02:46 -04:00
).nest(
"/object",
Router::new()
2025-04-02 18:23:03 -04:00
.route("/{addr}", get({
2025-05-02 16:32:39 -04:00
let objects = graph.objects.clone();
move |addr| object_path(objects, addr)
}))
2025-03-30 15:02:46 -04:00
),
)
2025-03-30 21:18:08 -04:00
.route("/lib/client.js", get(get_client_js))
.route("/ui/", get(|| async { Html(include_str!("../static/index.html")).into_response() }))
2025-03-29 20:32:25 -04:00
}
2025-03-30 15:02:46 -04:00
// TODO(jwall): Javascript test script
2025-03-29 20:32:25 -04:00
pub async fn serve() {
// run our app with hyper, listening globally on port 3000
2025-05-02 16:32:39 -04:00
let graph = Graph::random_graph();
2025-03-30 15:02:46 -04:00
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
println!("Server ui starting on http://127.0.0.1:3000/ui/");
2025-05-02 16:32:39 -04:00
axum::serve(listener, endpoints(graph)).await.unwrap();
2025-03-28 17:46:09 -04:00
}