use actix_web::{get, web, App, HttpResponse, HttpServer}; use rust_embed::RustEmbed; use sea_orm::{Database, DatabaseConnection}; use tracing::{info, instrument}; use tracing_subscriber::prelude::*; mod api; mod auth; mod entity; mod error; #[cfg(all(target_env = "musl", target_pointer_width = "64"))] #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; #[derive(Debug)] pub struct AppState { pub db: DatabaseConnection, } #[actix_web::main] async fn main() { let subscriber = tracing_subscriber::registry().with( tracing_subscriber::fmt::Layer::new() .pretty() .with_writer(std::io::stdout) .with_ansi(true) .with_filter(tracing_subscriber::filter::LevelFilter::TRACE), ); tracing::subscriber::set_global_default(subscriber).expect("Unable to set a global collector"); let db = setup_database().await.unwrap(); let state = web::Data::new(AppState { db }); info!("Starting http server on 8080"); HttpServer::new(move || { App::new() .app_data(state.clone()) .wrap(tracing_actix_web::TracingLogger::default()) .service(api::routes()) .service(dist) }) .bind("0.0.0.0:8080") .unwrap() .run() .await .expect("Couldnt launch server"); } #[derive(RustEmbed)] #[folder = "dist"] struct UIAssets; #[get("/{filename:.*}")] async fn dist(path: web::Path) -> HttpResponse { let path = if UIAssets::get(&*path).is_some() { &*path } else { "index.html" }; let content = UIAssets::get(path).unwrap(); let body: actix_web::body::BoxBody = match content { std::borrow::Cow::Borrowed(bytes) => actix_web::body::BoxBody::new(bytes), std::borrow::Cow::Owned(bytes) => actix_web::body::BoxBody::new(bytes), }; HttpResponse::Ok() .content_type(mime_guess::from_path(path).first_or_octet_stream().as_ref()) .body(body) } #[instrument] async fn setup_database() -> error::Result { let pool = sqlx::SqlitePool::connect("sqlite://data.db").await?; sqlx::migrate!("./migrations").run(&pool).await?; tracing::info!("Database migrated"); Ok(Database::connect("sqlite://data.db").await?) }