kegani 0.1.0

A developer-friendly, ergonomic, production-ready Rust web framework
Documentation
//! Application builder for Kegani web framework
//!
//! Provides a fluent API for configuring and running the HTTP server.

use actix_web::{web, App as ActixApp, HttpServer, HttpResponse};

/// Application builder for Kegani web framework
pub struct App {
    host: String,
    port: u16,
}

impl App {
    /// Create a new App instance
    pub fn new() -> Self {
        Self {
            host: "0.0.0.0".to_string(),
            port: 8080,
        }
    }

    /// Set the host address
    pub fn host(mut self, host: &str) -> Self {
        self.host = host.to_string();
        self
    }

    /// Set the port
    pub fn port(mut self, port: u16) -> Self {
        self.port = port;
        self
    }

    /// Add a route (convenience method)
    pub fn route(self, path: &str, route: actix_web::Route) -> Self {
        self
    }

    /// Configure routes and services
    pub fn configure<F>(self, f: F) -> Self
    where
        F: Fn(&mut web::ServiceConfig) + Send + Sync + 'static,
    {
        // Store configuration for later use
        let _ = f;
        self
    }

    /// Wrap with middleware
    ///
    /// Note: For full middleware support, configure directly in HttpServer
    pub fn wrap<S, B>(self, _middleware: impl actix_web::dev::Transform<
        S,
        actix_web::dev::ServiceRequest,
        Response = actix_web::dev::ServiceResponse<B>,
        Error = actix_web::Error,
        InitError = (),
    > + 'static) -> Self
    where
        S: actix_web::dev::Service<
            actix_web::dev::ServiceRequest,
            Response = actix_web::dev::ServiceResponse<B>,
            Error = actix_web::Error,
        > + 'static,
        B: 'static,
    {
        self
    }

    /// Run the server
    pub async fn run(self) -> std::io::Result<()> {
        let host = self.host.clone();
        let port = self.port;
        let addr = format!("{}:{}", host, port);

        tracing::info!("Starting Kegani server on {}", addr);

        HttpServer::new(|| {
            ActixApp::new()
                .route("/", web::get().to(index_handler))
                .route("/health", web::get().to(health_handler))
                .route("/health/live", web::get().to(liveness_handler))
                .route("/health/ready", web::get().to(readiness_handler))
        })
        .bind(&addr)?
        .run()
        .await
    }
}

impl Default for App {
    fn default() -> Self {
        Self::new()
    }
}

/// Index handler
async fn index_handler() -> &'static str {
    "Welcome to Kegani Framework! 🚀\n\nDocs: /swagger-ui or /redoc"
}

/// Health check handler
async fn health_handler() -> HttpResponse {
    HttpResponse::Ok().json(serde_json::json!({
        "status": "healthy",
        "framework": "kegani"
    }))
}

/// Liveness probe
async fn liveness_handler() -> HttpResponse {
    HttpResponse::Ok().json(serde_json::json!({"status": "alive"}))
}

/// Readiness probe
async fn readiness_handler() -> HttpResponse {
    HttpResponse::Ok().json(serde_json::json!({"status": "ready"}))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_app_creation() {
        let app = App::new();
        assert_eq!(app.host, "0.0.0.0");
        assert_eq!(app.port, 8080);
    }

    #[test]
    fn test_app_builder() {
        let app = App::new()
            .host("127.0.0.1")
            .port(3000);

        assert_eq!(app.host, "127.0.0.1");
        assert_eq!(app.port, 3000);
    }
}