mod dem; use axum::{ extract::{Path, State}, http::Request, routing::get, Router }; use axum_macros::debug_handler; use std::env; use tower_http::{services::ServeDir, trace::{self, DefaultMakeSpan}}; use dem::DatasetRepository; use tracing::{info, Level, Span}; use tower_http::trace::TraceLayer; const DEFAULT_DATA_DIR: &str = "/data"; const DEFAULT_PORT: &str = "3000"; #[tokio::main] async fn main() { // initialize tracing tracing_subscriber::fmt::init(); let config = load_config().unwrap(); let cache = DatasetRepository::new(config.basedir); let serve_dir = ServeDir::new("assets"); let app = Router::new() .route("/elevation/:lat/:lon", get(get_elevation)) .nest_service("/", serve_dir) .with_state(cache) .layer( TraceLayer::new_for_http() .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) .on_response(trace::DefaultOnResponse::new().level(Level::INFO)), ); let host = format!("[::]:{}", config.port); info!("Will start server on {host}"); let listener = tokio::net::TcpListener::bind(host).await.unwrap(); axum::serve(listener, app).await.unwrap(); } #[debug_handler] async fn get_elevation(State(dsr): State, Path((lat, lon)): Path<(f64, f64)>) -> String { let ele = dem::elevation_from_coordinates(dsr, lat, lon); let myele = ele.await; format!("{myele}") } fn load_config() -> Result { Ok(Config { basedir: env::var("DEM_LOCATION").unwrap_or_else(|_| DEFAULT_DATA_DIR.to_string()), port: env::var("HTTP_PORT").unwrap_or_else(|_| DEFAULT_PORT.to_string()), }) } struct Config { basedir: String, port: String, }