mod db; mod routes; mod state; mod ws; use axum::{routing::get, Router}; use sqlx::sqlite::SqlitePoolOptions; use state::AppState; use std::env; use tower_http::services::{ServeDir, ServeFile}; #[tokio::main] async fn main() { let db_url = env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite:colony.db?mode=rwc".into()); let port = env::var("PORT").unwrap_or_else(|_| "3001".into()); let pool = SqlitePoolOptions::new() .max_connections(5) .connect(&db_url) .await .expect("Failed to connect to database"); eprintln!("colony: connected to {}", db_url); sqlx::query("PRAGMA journal_mode=WAL") .execute(&pool) .await .unwrap(); sqlx::migrate!("./migrations") .run(&pool) .await .expect("Failed to run migrations"); let state = AppState::new(pool); eprintln!("colony: migrations done, starting on port {}", port); let app = Router::new() .route("/api/health", get(routes::health)) .route("/api/users", get(routes::list_users)) .route("/api/me", get(routes::get_me)) .route( "/api/channels", get(routes::list_channels).post(routes::create_channel), ) .route("/api/channels/{id}", get(routes::get_channel)) .route( "/api/channels/{channel_id}/messages", get(routes::list_messages).post(routes::post_message), ) .route("/ws/{channel_id}", get(ws::ws_handler)) .fallback_service( ServeDir::new("static").fallback(ServeFile::new("static/index.html")), ) .with_state(state); let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)) .await .unwrap(); axum::serve(listener, app).await.unwrap(); }