cloudiful-server 0.2.0

Rust web server bootstrap crate with Actix and Axum adapters
Documentation
# cloudiful-server

Single crate server bootstrap library with shared config/TLS handling and
feature-gated Actix/Axum adapters.

Published to:

- crates.io as `cloudiful-server`
- Kellnr as `cloudiful-server`

## Features

- `actix` is enabled by default and keeps the existing `Server::new(config, |cfg| ...)` API
- `axum` adds `server::axum::Server` with native `Router` and `with_state` support

## Actix example

```rust
use actix_web::{HttpResponse, web};
use cloudiful_server::{CorsConfig, Server, ServerConfig};

#[derive(Debug)]
struct AppState {
    service_name: String,
}

#[actix_web::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::new()
        .with_listen_addr("127.0.0.1:3000")
        .with_app_data(web::Data::new(AppState {
            service_name: "orders".to_string(),
        }))
        .with_cors(CorsConfig::restricted(["https://intranet.example.com"]))
        .build()?;

    Server::new(config, |cfg| {
        cfg.route(
            "/health",
            web::get().to(|state: web::Data<AppState>| async move {
                HttpResponse::Ok().body(format!("{} ok", state.service_name))
            }),
        );
    })
    .start()
    .await?;

    Ok(())
}
```

## Axum example

```rust
use axum::{Router, extract::State, routing::get};
use cloudiful_server::{CorsConfig, ServerConfig};

#[derive(Clone)]
struct AppState {
    service_name: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ServerConfig::new()
        .with_listen_addr("127.0.0.1:3000")
        .with_app_data(AppState {
            service_name: "orders".to_string(),
        })
        .with_cors(CorsConfig::restricted(["https://intranet.example.com"]))
        .build()?;

    let app = Router::new().route(
        "/health",
        get(|State(state): State<AppState>| async move { format!("{} ok", state.service_name) }),
    );

    cloudiful_server::axum::Server::new_with_state(config, app)
        .start()
        .await?;

    Ok(())
}
```

## Testing

```bash
cargo test
cargo test --no-default-features --features axum
cargo test --all-features
```