use std::error::Error; use std::time::Duration; use actix_request_identifier::RequestIdentifier; use actix_web::{App, HttpResponse, HttpServer}; use actix_web::http::header::HeaderValue; use actix_web::web::{Data, JsonConfig}; use log::{info, Level}; use sea_orm::{ConnectOptions, Database, DatabaseConnection}; use tera::Tera; use starkingdoms_api_migration::{Migrator, MigratorTrait}; use crate::config::CONFIG; use crate::error::{APIError, APIErrorsResponse}; pub mod config; pub mod routes; pub mod error; pub struct AppState { pub conn: DatabaseConnection, pub templates: Tera } #[actix_web::main] async fn main() -> Result<(), Box> { simple_logger::init_with_level(Level::Debug).unwrap(); info!("Connecting to database at {}...", CONFIG.database.url); let mut opt = ConnectOptions::new(CONFIG.database.url.clone()); opt.max_connections(CONFIG.database.max_connections) .min_connections(CONFIG.database.min_connections) .connect_timeout(Duration::from_secs(CONFIG.database.connect_timeout)) .acquire_timeout(Duration::from_secs(CONFIG.database.acquire_timeout)) .idle_timeout(Duration::from_secs(CONFIG.database.idle_timeout)) .max_lifetime(Duration::from_secs(CONFIG.database.max_lifetime)) .sqlx_logging(CONFIG.database.sqlx_logging) .sqlx_logging_level(log::LevelFilter::Info); let db = Database::connect(opt).await?; info!("Performing database migration..."); Migrator::up(&db, None).await?; info!("Loading templates..."); let tera = Tera::new("templates/**/*.tera")?; let data = Data::new(AppState { conn: db, templates: tera }); HttpServer::new(move || { App::new() .app_data(data.clone()) .app_data(JsonConfig::default().error_handler(|err, _req| { let api_error: APIError = (&err).into(); actix_web::error::InternalError::from_response( err, HttpResponse::BadRequest().json(APIErrorsResponse { errors: vec![ api_error ], }) ).into() })) .wrap(RequestIdentifier::with_generator(|| HeaderValue::from_str(&ulid::Ulid::new().to_string()).unwrap())) .service(routes::select_realm::select_realm) .service(routes::callback::callback) .service(actix_files::Files::new("/static", "static")) }).bind(CONFIG.server.bind)?.run().await?; Ok(()) }