kegani 0.1.0

A developer-friendly, ergonomic, production-ready Rust web framework
Documentation
//! Swagger UI and ReDoc integration
//!
//! Provides routes for OpenAPI documentation UI.

use actix_web::{web, HttpResponse, Responder};

/// Swagger UI handler
pub async fn swagger_ui_handler() -> impl Responder {
    let html = r#"
<!DOCTYPE html>
<html>
<head>
    <title>Kegani API Documentation</title>
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
</head>
<body>
    <div id="swagger-ui"></div>
    <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
    <script>
        window.onload = function() {
            SwaggerUIBundle({
                url: "/api-docs/openapi.json",
                dom_id: '#swagger-ui',
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIBundle.SwaggerUIStandalonePreset
                ],
                layout: "BaseLayout"
            });
        };
    </script>
</body>
</html>
"#;
    HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body(html)
}

/// ReDoc handler
pub async fn redoc_handler() -> impl Responder {
    let html = r#"
<!DOCTYPE html>
<html>
<head>
    <title>Kegani API Documentation - ReDoc</title>
    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/redoc@latest/bundles/redoc.standalone.js">
</head>
<body>
    <redoc spec-url='/api-docs/openapi.json'></redoc>
    <script src="https://unpkg.com/redoc@latest/bundles/redoc.standalone.js"></script>
</body>
</html>
"#;
    HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body(html)
}

/// OpenAPI JSON handler
pub async fn openapi_json_handler() -> impl Responder {
    HttpResponse::Ok()
        .content_type("application/json")
        .json(serde_json::json!({
            "openapi": "3.0.3",
            "info": {
                "title": "Kegani API",
                "version": "1.0.0"
            },
            "paths": {}
        }))
}

/// Swagger UI configuration
pub struct SwaggerUi {
    path: String,
    spec_path: String,
}

impl SwaggerUi {
    /// Create a new Swagger UI
    pub fn new(path: &str) -> Self {
        Self {
            path: path.to_string(),
            spec_path: "/api-docs/openapi.json".to_string(),
        }
    }

    /// Set the spec URL
    pub fn url(mut self, url: &str) -> Self {
        self.spec_path = url.to_string();
        self
    }

    /// Configure routes
    pub fn configure(self, cfg: &mut web::ServiceConfig) {
        let spec_path = self.spec_path.clone();
        cfg.route(&self.path, web::get().to(move || {
            let html = format!(r#"
<!DOCTYPE html>
<html>
<head>
    <title>Kegani API Documentation</title>
    <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
</head>
<body>
    <div id="swagger-ui"></div>
    <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
    <script>
        window.onload = function() {{
            SwaggerUIBundle({{
                url: "{spec_path}",
                dom_id: '#swagger-ui',
                presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
                layout: "BaseLayout"
            }});
        }};
    </script>
</body>
</html>
"#, spec_path = spec_path);
            async move {
                HttpResponse::Ok()
                    .content_type("text/html; charset=utf-8")
                    .body(html)
            }
        }));
    }
}

/// ReDoc configuration
pub struct ReDoc {
    path: String,
    spec_path: String,
}

impl ReDoc {
    /// Create a new ReDoc
    pub fn new(path: &str) -> Self {
        Self {
            path: path.to_string(),
            spec_path: "/api-docs/openapi.json".to_string(),
        }
    }

    /// Set the spec URL
    pub fn url(mut self, url: &str) -> Self {
        self.spec_path = url.to_string();
        self
    }

    /// Configure routes
    pub fn configure(self, cfg: &mut web::ServiceConfig) {
        let spec_path = self.spec_path.clone();
        cfg.route(&self.path, web::get().to(move || {
            let html = format!(r#"
<!DOCTYPE html>
<html>
<head>
    <title>Kegani API - ReDoc</title>
    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
</head>
<body>
    <redoc spec-url='{spec_path}'></redoc>
    <script src="https://unpkg.com/redoc@latest/bundles/redoc.standalone.js"></script>
</body>
</html>
"#, spec_path = spec_path);
            async move {
                HttpResponse::Ok()
                    .content_type("text/html; charset=utf-8")
                    .body(html)
            }
        }));
    }
}