|
| 1 | +use axum::{ |
| 2 | + Json, Router, |
| 3 | + routing::{get, get_service}, |
| 4 | +}; |
| 5 | +use clap::Parser; |
| 6 | +use std::{net::SocketAddr, path::PathBuf}; |
| 7 | +use tower_http::services::ServeFile; |
| 8 | +use tracing_subscriber::EnvFilter; |
| 9 | + |
| 10 | +/// A simple server to serve WASM files |
| 11 | +#[derive(Parser, Debug)] |
| 12 | +struct Args { |
| 13 | + /// List of .wasm files to serve |
| 14 | + #[arg(required = true, num_args = 1..)] |
| 15 | + files: Vec<PathBuf>, |
| 16 | + |
| 17 | + #[arg(short, long, default_value_t = 0)] |
| 18 | + port: u16, |
| 19 | +} |
| 20 | + |
| 21 | +#[tokio::main] |
| 22 | +async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 23 | + tracing_subscriber::fmt() |
| 24 | + .with_env_filter(EnvFilter::from_default_env(/* RUST_LOG env var sets logging level */)) |
| 25 | + .init(); |
| 26 | + |
| 27 | + let args = Args::parse(); |
| 28 | + let mut app = Router::new(); |
| 29 | + |
| 30 | + let mut route_paths = vec![]; |
| 31 | + |
| 32 | + for path in args.files { |
| 33 | + if path.is_file() |
| 34 | + && let Some(unicode_path) = path.to_str() |
| 35 | + { |
| 36 | + let route_path = format!("/{}", unicode_path); |
| 37 | + let service = get_service(ServeFile::new(&path)); |
| 38 | + app = app.route(&route_path, service); |
| 39 | + |
| 40 | + tracing::info!("serving file {:?} at route {}", path, route_path); |
| 41 | + route_paths.push(route_path); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + app = app.route("/", get(Json(route_paths))); |
| 46 | + |
| 47 | + let addr = SocketAddr::from(([0, 0, 0, 0], args.port)); |
| 48 | + let listener = tokio::net::TcpListener::bind(addr).await?; |
| 49 | + let local_addr = listener.local_addr()?; |
| 50 | + |
| 51 | + tracing::info!("listening on {}", local_addr); |
| 52 | + axum::serve(listener, app).await?; |
| 53 | + |
| 54 | + Ok(()) |
| 55 | +} |
0 commit comments