use std::net::SocketAddr; use std::sync::Arc; use axum::Router; use clap::Parser; use extension_registry::{ExtensionRegistry, API_VERSION, DEFAULT_PORT}; use tokio::net::TcpListener; mod handlers; use handlers::{routes, AppState}; #[derive(Parser)] #[command(name = "extension-registry")] #[command(about = "OCI-compliant extension registry proxy", long_about = None)] struct Cli { /// Host to bind to #[arg(long, default_value = "127.0.0.1")] host: String, /// Port to bind to #[arg(long, default_value_t = DEFAULT_PORT)] port: u16, } #[tokio::main] async fn main() -> anyhow::Result<()> { // Initialize tracing tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::from_default_env() .add_directive("info".parse().unwrap()), ) .init(); // Parse CLI arguments let cli = Cli::parse(); // Create registry service let addr: SocketAddr = format!("{}:{}", cli.host, cli.port).parse()?; let registry = Arc::new(ExtensionRegistry::new(addr)); // Create application state let state = AppState::new(registry); // Build router let app: Router = routes(state); // Bind to address let listener = TcpListener::bind(addr).await?; tracing::info!( "extension-registry v{} starting on {} (OCI v2 API)", API_VERSION, addr ); // Run server axum::serve(listener, app).await?; Ok(()) }