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