use askama::Template; use axum::{ extract::State, response::{Html, IntoResponse}, routing::get, Router, }; use sqlx::{sqlite::{SqliteConnectOptions, SqlitePoolOptions}, SqlitePool}; use std::str::FromStr; use std::sync::Arc; use tokio::net::TcpListener; use std::env; #[derive(Clone)] struct AppState { db: SqlitePool, } #[derive(Template)] #[template(path = "index.html")] struct IndexTemplate { title: String, } struct HtmlTemplate(T); impl IntoResponse for HtmlTemplate where T: Template, { fn into_response(self) -> axum::response::Response { match self.0.render() { Ok(html) => Html(html).into_response(), Err(err) => ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to render template: {}", err), ) .into_response(), } } } async fn index(State(_state): State>) -> impl IntoResponse { let template = IndexTemplate { title: "Coming Soon".to_string(), }; HtmlTemplate(template) } #[tokio::main] async fn main() { dotenvy::dotenv().ok(); let db_url = env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite://data.db".to_string()); let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string()); let addr = format!("0.0.0.0:{}", port); let db_opts = SqliteConnectOptions::from_str(&db_url) .expect("Failed to parse DATABASE_URL") .create_if_missing(true); let db_pool = SqlitePoolOptions::new() .max_connections(5) .connect_with(db_opts) .await .expect("Failed to connect to SQLite database"); let app_state = Arc::new(AppState { db: db_pool }); let app = Router::new() .route("/", get(index)) .with_state(app_state); let listener = TcpListener::bind(&addr).await.unwrap(); println!("Server running at http://{}", addr); axum::serve(listener, app).await.unwrap(); }