Skip to main content

rust_api/
server.rs

1//! Server runtime for RustAPI framework
2//!
3//! Provides the main `RustAPI` struct for configuring and running the HTTP server.
4
5use crate::error::Result;
6use crate::router::Router;
7use std::net::SocketAddr;
8
9/// Main RustAPI server struct with builder pattern for configuration
10///
11/// # Example
12///
13/// ```ignore
14/// let app = Router::new().route("/", get(handler));
15///
16/// RustAPI::new(app)
17///     .port(8080)
18///     .serve()
19///     .await?;
20/// ```
21pub struct RustAPI {
22    router: Router,
23    port: u16,
24    host: String,
25}
26
27impl RustAPI {
28    /// Create a new RustAPI server with the given router
29    ///
30    /// Defaults to running on `0.0.0.0:3000`
31    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    /// Set the port to listen on (default: 3000)
40    pub fn port(mut self, port: u16) -> Self {
41        self.port = port;
42        self
43    }
44
45    /// Set the host to bind to (default: "0.0.0.0")
46    pub fn host(mut self, host: impl Into<String>) -> Self {
47        self.host = host.into();
48        self
49    }
50
51    /// Start the HTTP server
52    ///
53    /// This will bind to the configured host and port, and start serving requests.
54    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        // Router is already Axum's router (type alias), serve it directly
66        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}