use std::{future::IntoFuture, net::Ipv4Addr};
use axum::Router;
use futures::FutureExt as _;
use tokio::{net::TcpListener, sync::oneshot};
pub struct HttpServer {
port: u16,
_shutdown_sender: oneshot::Sender<()>,
}
impl HttpServer {
pub async fn start(router: Router) -> anyhow::Result<Self> {
let (shutdown_sender, shutdown_receiver) = oneshot::channel();
let shutdown_signal = shutdown_receiver.map(|_| ());
let listener = TcpListener::bind((Ipv4Addr::from([127, 0, 0, 1]), 0)).await?;
let port = listener.local_addr()?.port();
tokio::spawn(
axum::serve(listener, router)
.with_graceful_shutdown(shutdown_signal)
.into_future(),
);
Ok(HttpServer {
port,
_shutdown_sender: shutdown_sender,
})
}
pub fn url(&self) -> String {
format!("http://{}:{}", self.hostname(), self.port())
}
pub fn hostname(&self) -> String {
"localhost".to_owned()
}
pub fn port(&self) -> u16 {
self.port
}
}