use actix_web::{App, HttpServer, middleware::Logger, web::Data}; use clap::Parser; use utoipa::OpenApi; use crate::cli::{CliArgs, Command}; mod api; mod app; mod cli; mod storage; #[actix_web::main] #[expect( clippy::needless_for_each, reason = "utoipa generates this, we can't change it" )] async fn main() -> Result<(), std::io::Error> { #[derive(OpenApi)] #[openapi( paths( api::get::product_by_id, api::get::products, api::set::register_product, api::set::associate_barcode ), // security( // (), // ("my_auth" = ["read:items", "edit:items"]), // ("token_jwt" = []) // ), )] struct ApiDoc; env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); let args = CliArgs::parse(); match args.command { Command::Serve => { let host = "127.0.0.1"; let port = 8080; let data = Data::new( app::App::new() .await .map_err(|err| std::io::Error::other(main::Error::AppInit(err)))?, ); eprintln!("Serving at http://{host}:{port}"); HttpServer::new(move || { App::new() .wrap(Logger::default()) .app_data(Data::clone(&data)) .configure(api::get::register_paths) .configure(api::set::register_paths) }) .bind((host, port))? .run() .await } Command::OpenApi => { let openapi = ApiDoc::openapi(); println!("{}", openapi.to_pretty_json().expect("Comp-time constant")); Ok(()) } } } pub(crate) mod main { use crate::app::app_create; #[derive(thiserror::Error, Debug)] pub(crate) enum Error { #[error("Failed to initialize shared application state: {0}")] AppInit(#[from] app_create::Error), } }