use std::{collections::HashMap, sync::Arc}; use axum::{ extract::Path, http, response::{Html, IntoResponse}, routing::get, Json, Router, }; use offline_web_model::{Graph, Reference}; // TODO(jeremy): Allow this to autoexpand the content_addresses? async fn all_references(root_ref: Arc) -> Json> { Json(root_ref) } async fn ref_path( refs: Arc>>, Path(path): Path, ) -> Json> { let path = format!("/item/{}", path); match refs.get(&path) { Some(r) => Json(r.clone()), None => todo!("Return a 404?"), } } async fn object_path(objects: Arc>>, Path(addr): Path) -> Vec { dbg!(&addr); match objects.get(&addr) { Some(o) => o.clone(), None => todo!("Return a 404?"), } } async fn get_client_js() -> impl IntoResponse { ( [(http::header::CONTENT_TYPE, "application/javascript")], include_str!("../static/client.js"), ) } pub fn endpoints(graph: Graph) -> Router { Router::new() .nest( "/api/v1", Router::new() .nest( "/ref", Router::new() .route( "/all/username", get({ let state = graph.root.clone(); move || all_references(state) }), ) .route( "/item/{*path}", get({ let refs = graph.refs.clone(); move |path| ref_path(refs, path) }), ), ) .nest( "/object", Router::new().route( "/{addr}", get({ let objects = graph.objects.clone(); move |addr| object_path(objects, addr) }), ), ), ) .route("/lib/client.js", get(get_client_js)) .route( "/ui/", get(|| async { Html(include_str!("../static/index.html")).into_response() }), ) } // TODO(jwall): Javascript test script pub async fn serve() { // run our app with hyper, listening globally on port 3000 let graph = Graph::random_graph(); 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/"); axum::serve(listener, endpoints(graph)).await.unwrap(); }