doido_controller/
server.rs1use crate::config::{self, ServerConfig};
4use crate::stack::MiddlewareStack;
5
6fn resolve_addr(server: &ServerConfig, bind: Option<&str>, port: Option<u16>) -> String {
9 let bind = bind.unwrap_or(&server.bind);
10 let port = port.unwrap_or(server.port);
11 format!("{bind}:{port}")
12}
13
14pub async fn start_server(router: axum::Router) -> std::io::Result<()> {
18 start_server_with(router, None, None).await
19}
20
21pub async fn start_server_with(
24 router: axum::Router,
25 bind: Option<String>,
26 port: Option<u16>,
27) -> std::io::Result<()> {
28 let config = config::load();
29 let addr = resolve_addr(config.server(), bind.as_deref(), port);
30
31 let router = MiddlewareStack::default().apply(router);
34
35 let listener = tokio::net::TcpListener::bind(&addr).await?;
36 tracing::info!("listening on http://{addr}");
37 tracing::info!("routes:\n{}", crate::route_table::format_routes());
38 axum::serve(listener, router).await
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn resolve_addr_prefers_overrides_then_config() {
47 let server = ServerConfig {
48 bind: "0.0.0.0".into(),
49 port: 3000,
50 };
51 assert_eq!(resolve_addr(&server, None, None), "0.0.0.0:3000");
52 assert_eq!(resolve_addr(&server, None, Some(4000)), "0.0.0.0:4000");
53 assert_eq!(
54 resolve_addr(&server, Some("127.0.0.1"), None),
55 "127.0.0.1:3000"
56 );
57 assert_eq!(
58 resolve_addr(&server, Some("127.0.0.1"), Some(8080)),
59 "127.0.0.1:8080"
60 );
61 }
62}