diff --git a/src/lib.rs b/src/lib.rs index 503c7ab..613c148 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ //! use live_server::listen; //! //! async fn serve() { -//! listen("127.0.0.1", 8080, "./").await.unwrap(); +//! listen("127.0.0.1", 8080, "./", true).await.unwrap(); //! } //! ``` //! @@ -31,13 +31,14 @@ static TX: OnceCell> = OnceCell::const_new(); /// use live_server::listen; /// /// async fn serve() { -/// listen("127.0.0.1", 8080, "./").await.unwrap(); +/// listen("127.0.0.1", 8080, "./", true).await.unwrap(); /// } /// ``` pub async fn listen>( host: &str, port: u16, root: R, + try_to_switch_to_an_available_port: bool ) -> Result<(), Box> { HOST.set(host.to_string()).unwrap(); ROOT.set(root.into()).unwrap(); @@ -45,9 +46,10 @@ pub async fn listen>( TX.set(tx).unwrap(); let watcher_future = tokio::spawn(watcher::watch()); - let server_future = tokio::spawn(server::serve(port)); + let server_future = tokio::spawn(server::serve(port, try_to_switch_to_an_available_port)); - tokio::try_join!(watcher_future, server_future)?; + let (_, server_result) = tokio::try_join!(watcher_future, server_future)?; + server_result?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 7660319..d27d9b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,5 +38,5 @@ async fn main() { }, }; - listen(&host, args.port, args.root).await.unwrap(); + listen(&host, args.port, args.root, true).await.unwrap(); } diff --git a/src/server.rs b/src/server.rs index 1aea396..4eacbc0 100644 --- a/src/server.rs +++ b/src/server.rs @@ -13,13 +13,15 @@ use tokio::net::TcpListener; use crate::{HOST, PORT, ROOT, TX}; -pub async fn serve(port: u16) { - let listener = create_listener(port).await; +pub async fn serve(port: u16, switch_to_available_ports: bool) -> Result<(), String> { + let listener = create_listener(port, switch_to_available_ports).await?; let app = create_server(); axum::serve(listener, app).await.unwrap(); + + Ok(()) } -async fn create_listener(port: u16) -> TcpListener { +async fn create_listener(port: u16, switch_to_available_ports: bool) -> Result { let host = HOST.get().unwrap(); let mut port = port; // Loop until the port is available @@ -28,12 +30,17 @@ async fn create_listener(port: u16) -> TcpListener { Ok(listener) => { log::info!("Listening on http://{}:{}/", host, port); PORT.set(port).unwrap(); - break listener; + break Ok(listener); } Err(err) => { if let std::io::ErrorKind::AddrInUse = err.kind() { - log::warn!("Port {} is already in use", port); - port += 1; + if switch_to_available_ports { + log::warn!("Port {} is already in use", port); + port += 1; + } else { + log::error!("Port {} is already in use", port); + return Err(format!("Port {} is already in use", port)); + } } else { log::error!("Failed to listen on {}:{}: {}", host, port, err); } diff --git a/tests/test.rs b/tests/test.rs index 494111b..881da9f 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -4,7 +4,7 @@ use reqwest::StatusCode; #[tokio::test] async fn request() { tokio::spawn(async { - listen("127.0.0.1", 8000, "./tests/page").await.unwrap(); + listen("127.0.0.1", 8000, "./tests/page", false).await.unwrap(); }); // Test requesting index.html