From 7c9fdd8ffbd883e957eb8245a2b4162c9d314b1a Mon Sep 17 00:00:00 2001 From: "Shahar \"Dawn\" Or" Date: Thu, 12 Oct 2023 21:27:04 +0700 Subject: [PATCH] ssg: move some code around --- ssg-parent/src/{dev => }/app.rs | 0 ssg-parent/src/{dev => }/app/state.rs | 0 ssg-parent/src/dev.rs | 101 ------------------------- ssg-parent/src/lib.rs | 104 +++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 105 deletions(-) rename ssg-parent/src/{dev => }/app.rs (100%) rename ssg-parent/src/{dev => }/app/state.rs (100%) delete mode 100644 ssg-parent/src/dev.rs diff --git a/ssg-parent/src/dev/app.rs b/ssg-parent/src/app.rs similarity index 100% rename from ssg-parent/src/dev/app.rs rename to ssg-parent/src/app.rs diff --git a/ssg-parent/src/dev/app/state.rs b/ssg-parent/src/app/state.rs similarity index 100% rename from ssg-parent/src/dev/app/state.rs rename to ssg-parent/src/app/state.rs diff --git a/ssg-parent/src/dev.rs b/ssg-parent/src/dev.rs deleted file mode 100644 index 09b15239..00000000 --- a/ssg-parent/src/dev.rs +++ /dev/null @@ -1,101 +0,0 @@ -pub(crate) mod app; - -use futures::FutureExt; -use reactive::driver::Driver; - -use crate::Parent; - -/// Error type returned from the reactive app -#[derive(Debug, thiserror::Error)] -#[allow(clippy::module_name_repetitions)] -pub enum DevError { - #[error(transparent)] - Notify(#[from] reactive::driver::notify::Error), - #[error(transparent)] - Io(std::io::Error), - #[error("no free port")] - NoFreePort, -} - -const BUILDER_CRATE_NAME: &str = "builder"; -const LOCALHOST: &str = "localhost"; - -fn local_url(port: portpicker::Port) -> reqwest::Url { - reqwest::Url::parse(&format!("http://{LOCALHOST}:{port}")).expect("valid") -} - -impl Parent { - /// Sets up a development environment that watches the file system, - /// recompiling the crate that when run describes the website on localhost when there are changes. - pub async fn dev(self, launch_browser: bool) -> DevError { - let Some(port) = portpicker::pick_unused_port() else { - return DevError::NoFreePort; - }; - - let server_task = - live_server::listen(LOCALHOST, port, self.output_dir.as_std_path().to_owned()) - .map(|result| result.expect_err("unreachable")) - .boxed(); - - let mut cargo_run_builder = tokio::process::Command::new("cargo"); - cargo_run_builder.args([ - "run", - "--package", - BUILDER_CRATE_NAME, - "--", - self.output_dir.as_str(), - ]); - - let url = local_url(port); - - let (builder_driver, builder_started) = - reactive::driver::command::StaticCommandDriver::new(cargo_run_builder); - let (child_process_killer_driver, child_killed) = - reactive::driver::child_process_killer::ChildProcessKillerDriver::new(); - let (open_browser_driver, browser_opened) = - reactive::driver::open_that::StaticOpenThatDriver::new(url.to_string()); - let (eprintln_driver, ()) = reactive::driver::println::EprintlnDriver::new(); - let (notify_driver, notify) = - match reactive::driver::notify::FsChangeDriver::new(BUILDER_CRATE_NAME) { - Ok(val) => val, - Err(e) => return e.into(), - }; - - let inputs = app::Inputs { - server_task, - child_killed, - notify, - builder_started, - launch_browser, - browser_opened, - url, - }; - - let outputs = self.outputs(inputs); - - let app::Outputs { - stderr, - open_browser, - error, - kill_child, - run_builder, - stream_splitter_task, - } = outputs; - - let builder_driver_task = builder_driver.init(run_builder); - let child_process_killer_driver_task = child_process_killer_driver.init(kill_child); - let open_browser_driver_task = open_browser_driver.init(open_browser); - let stderr_driver_task = eprintln_driver.init(stderr); - let notify_driver_task = notify_driver.init(()); - - futures::select! { - error = error.fuse() => error, - () = builder_driver_task.fuse() => unreachable!(), - () = child_process_killer_driver_task.fuse() => unreachable!(), - () = stderr_driver_task.fuse() => unreachable!(), - () = open_browser_driver_task.fuse() => unreachable!(), - () = stream_splitter_task.fuse() => unreachable!(), - () = notify_driver_task.fuse() => unreachable!(), - } - } -} diff --git a/ssg-parent/src/lib.rs b/ssg-parent/src/lib.rs index 6667f41f..26fd02ea 100644 --- a/ssg-parent/src/lib.rs +++ b/ssg-parent/src/lib.rs @@ -1,13 +1,35 @@ #![warn(clippy::all, clippy::pedantic)] -mod dev; -use dev::app::state::BuilderState; -pub use dev::DevError; +pub(crate) mod app; + +use futures::FutureExt; +use reactive::driver::Driver; + +use app::state::BuilderState; #[derive(Debug)] pub struct Parent { output_dir: camino::Utf8PathBuf, - builder: dev::app::state::BuilderState, + builder: app::state::BuilderState, +} + +const BUILDER_CRATE_NAME: &str = "builder"; +const LOCALHOST: &str = "localhost"; + +/// Error type returned from the reactive app +#[derive(Debug, thiserror::Error)] +#[allow(clippy::module_name_repetitions)] +pub enum DevError { + #[error(transparent)] + Notify(#[from] reactive::driver::notify::Error), + #[error(transparent)] + Io(std::io::Error), + #[error("no free port")] + NoFreePort, +} + +fn local_url(port: portpicker::Port) -> reqwest::Url { + reqwest::Url::parse(&format!("http://{LOCALHOST}:{port}")).expect("valid") } impl Parent { @@ -17,4 +39,78 @@ impl Parent { builder: BuilderState::default(), } } + + /// Sets up a development environment that watches the file system, + /// recompiling the crate that when run describes the website on localhost when there are changes. + pub async fn dev(self, launch_browser: bool) -> DevError { + let Some(port) = portpicker::pick_unused_port() else { + return DevError::NoFreePort; + }; + + let server_task = + live_server::listen(LOCALHOST, port, self.output_dir.as_std_path().to_owned()) + .map(|result| result.expect_err("unreachable")) + .boxed(); + + let mut cargo_run_builder = tokio::process::Command::new("cargo"); + cargo_run_builder.args([ + "run", + "--package", + BUILDER_CRATE_NAME, + "--", + self.output_dir.as_str(), + ]); + + let url = local_url(port); + + let (builder_driver, builder_started) = + reactive::driver::command::StaticCommandDriver::new(cargo_run_builder); + let (child_process_killer_driver, child_killed) = + reactive::driver::child_process_killer::ChildProcessKillerDriver::new(); + let (open_browser_driver, browser_opened) = + reactive::driver::open_that::StaticOpenThatDriver::new(url.to_string()); + let (eprintln_driver, ()) = reactive::driver::println::EprintlnDriver::new(); + let (notify_driver, notify) = + match reactive::driver::notify::FsChangeDriver::new(BUILDER_CRATE_NAME) { + Ok(val) => val, + Err(e) => return e.into(), + }; + + let inputs = app::Inputs { + server_task, + child_killed, + notify, + builder_started, + launch_browser, + browser_opened, + url, + }; + + let outputs = self.outputs(inputs); + + let app::Outputs { + stderr, + open_browser, + error, + kill_child, + run_builder, + stream_splitter_task, + } = outputs; + + let builder_driver_task = builder_driver.init(run_builder); + let child_process_killer_driver_task = child_process_killer_driver.init(kill_child); + let open_browser_driver_task = open_browser_driver.init(open_browser); + let stderr_driver_task = eprintln_driver.init(stderr); + let notify_driver_task = notify_driver.init(()); + + futures::select! { + error = error.fuse() => error, + () = builder_driver_task.fuse() => unreachable!(), + () = child_process_killer_driver_task.fuse() => unreachable!(), + () = stderr_driver_task.fuse() => unreachable!(), + () = open_browser_driver_task.fuse() => unreachable!(), + () = stream_splitter_task.fuse() => unreachable!(), + () = notify_driver_task.fuse() => unreachable!(), + } + } }