1use crate::builder::ServerBuilder;
4use crate::error::{Error, Result};
5use crate::shutdown::shutdown_signal;
6use axum::Router;
7use std::net::SocketAddr;
8use std::time::Duration;
9use tokio::net::TcpListener;
10
11pub struct Server {
15 router: Router<()>,
16 listener: TcpListener,
17 local_addr: SocketAddr,
18 shutdown_timeout: Option<Duration>,
19}
20
21impl Server {
22 pub fn builder() -> ServerBuilder {
24 ServerBuilder::new()
25 }
26
27 pub(crate) fn from_parts(
29 router: Router<()>,
30 listener: TcpListener,
31 local_addr: SocketAddr,
32 shutdown_timeout: Option<Duration>,
33 ) -> Self {
34 Self {
35 router,
36 listener,
37 local_addr,
38 shutdown_timeout,
39 }
40 }
41
42 #[must_use]
46 pub fn local_addr(&self) -> SocketAddr {
47 self.local_addr
48 }
49
50 pub async fn run(self) -> Result<()> {
54 self.run_with_shutdown(shutdown_signal()).await
55 }
56
57 pub async fn run_with_shutdown<F>(self, shutdown: F) -> Result<()>
64 where
65 F: std::future::Future<Output = ()> + Send + 'static,
66 {
67 let timeout = self.shutdown_timeout;
68 let serve = axum::serve(self.listener, self.router).with_graceful_shutdown(shutdown);
69 match timeout {
70 Some(d) => match tokio::time::timeout(d, serve).await {
71 Ok(res) => res.map_err(Error::from),
72 Err(_) => Err(Error::ShutdownTimeout(d)),
73 },
74 None => serve.await.map_err(Error::from),
75 }
76 }
77}