1use std::net::SocketAddr;
7
8use crate::{error::Result, router::Router};
9
10pub struct RustAPI {
23 router: Router,
24 port: u16,
25 host: String,
26}
27
28impl RustAPI {
29 pub fn new(router: Router) -> Self {
33 Self {
34 router,
35 port: 3000,
36 host: "0.0.0.0".to_string(),
37 }
38 }
39
40 pub fn port(mut self, port: u16) -> Self {
42 self.port = port;
43 self
44 }
45
46 pub fn host(mut self, host: impl Into<String>) -> Self {
48 self.host = host.into();
49 self
50 }
51
52 pub async fn serve(self) -> Result<()> {
57 let addr = format!("{}:{}", self.host, self.port);
58 let socket_addr: SocketAddr = addr.parse().map_err(|e| {
59 crate::error::Error::server_error(format!("Invalid address {}: {}", addr, e))
60 })?;
61
62 let listener = tokio::net::TcpListener::bind(socket_addr)
63 .await
64 .map_err(|e| {
65 crate::error::Error::server_error(format!(
66 "Failed to bind to {}: {}",
67 socket_addr, e
68 ))
69 })?;
70
71 tracing::info!("Server running on http://{}", socket_addr);
72
73 axum::serve(listener, self.router)
75 .await
76 .map_err(|e| crate::error::Error::server_error(format!("Server error: {}", e)))
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_rust_api_defaults() {
86 let router = crate::router::build();
87 let server = RustAPI::new(router);
88 assert_eq!(server.port, 3000);
89 assert_eq!(server.host, "0.0.0.0");
90 }
91
92 #[test]
93 fn test_rust_api_builder() {
94 let router = crate::router::build();
95 let server = RustAPI::new(router).port(8080).host("127.0.0.1");
96 assert_eq!(server.port, 8080);
97 assert_eq!(server.host, "127.0.0.1");
98 }
99}