Skip to main content

claw_spawn/server/
mod.rs

1//! HTTP server support (standalone + embeddable).
2//!
3//! This module mirrors the pattern used by other Cedros services:
4//! - **Standalone**: `claw-spawn-server` binary calls `run()`
5//! - **Embedded**: host Axum app calls `router(state)` (and may nest it)
6
7mod http;
8mod state;
9
10pub use http::router;
11pub use state::{build_state_from_env, build_state_with_pool, AppState};
12
13use crate::infrastructure::AppConfig;
14use anyhow::Context;
15use std::net::SocketAddr;
16use tokio::net::TcpListener;
17use tracing::info;
18
19/// Standalone entrypoint for the `claw-spawn-server` binary.
20pub async fn run() -> anyhow::Result<()> {
21    tracing_subscriber::fmt::init();
22    dotenvy::dotenv().ok();
23
24    let config = AppConfig::from_env().context("load config")?;
25    let state = build_state_from_env(config.clone()).await?;
26
27    let addr: SocketAddr = format!("{}:{}", config.server_host, config.server_port)
28        .parse()
29        .context("parse listen address")?;
30    let listener = TcpListener::bind(addr).await.context("bind listener")?;
31
32    info!(
33        host = %config.server_host,
34        port = config.server_port,
35        "Server running"
36    );
37    info!(
38        docs = %format!("http://{}:{}/docs", config.server_host, config.server_port),
39        "API docs"
40    );
41
42    let app = router(state);
43    axum::serve(listener, app).await.context("serve")?;
44    Ok(())
45}