diff --git a/ssg-parent/src/dev.rs b/ssg-parent/src/dev.rs index 13fc0dec..239dd60d 100644 --- a/ssg-parent/src/dev.rs +++ b/ssg-parent/src/dev.rs @@ -65,7 +65,7 @@ where url, }; - let outputs = app::app(inputs); + let outputs = app::App::default().outputs(inputs); let app::Outputs { stderr, diff --git a/ssg-parent/src/dev/app.rs b/ssg-parent/src/dev/app.rs index ded60afc..dc3a4bfc 100644 --- a/ssg-parent/src/dev/app.rs +++ b/ssg-parent/src/dev/app.rs @@ -1,5 +1,11 @@ mod state; +/// State machine for the dev environment +#[derive(Debug, Default)] +pub(super) struct App { + builder: state::BuilderState, +} + use colored::Colorize; use futures::{ channel::mpsc, @@ -48,89 +54,90 @@ pub(super) struct Outputs { pub(super) stream_splitter_task: LocalBoxFuture<'static, ()>, } -/// Initializes the state machine for the dev environment -pub(super) fn app(inputs: Inputs) -> Outputs { - let Inputs { - server_task, - child_killed, - notify: builder_crate_fs_change, - builder_started, - launch_browser, - browser_opened: browser_launch, - url: local_host_port_url, - } = inputs; +impl App { + pub(super) fn outputs(self, inputs: Inputs) -> Outputs { + let Inputs { + server_task, + child_killed, + notify: builder_crate_fs_change, + builder_started, + launch_browser, + browser_opened: browser_launch, + url: local_host_port_url, + } = inputs; - let message = format!("\nServer started at {local_host_port_url}\n") - .blue() - .to_string(); + let message = format!("\nServer started at {local_host_port_url}\n") + .blue() + .to_string(); - let mut initial = vec![OutputEvent::RunBuilder, OutputEvent::Stderr(message)]; - if launch_browser { - initial.push(OutputEvent::OpenBrowser); - } - let initial = stream::iter(initial); + let mut initial = vec![OutputEvent::RunBuilder, OutputEvent::Stderr(message)]; + if launch_browser { + initial.push(OutputEvent::OpenBrowser); + } + let initial = stream::iter(initial); - let reaction = stream::select_all([ - stream::once(server_task) - .map(InputEvent::ServerError) - .boxed_local(), - child_killed.map(InputEvent::BuilderKilled).boxed_local(), - builder_crate_fs_change - .map(InputEvent::FsChange) - .boxed_local(), - builder_started - .map(InputEvent::BuilderStarted) - .boxed_local(), - browser_launch.map(InputEvent::BrowserOpened).boxed_local(), - ]) - .scan(state::State::default(), move |state, input| { - future::ready(Some(state.input_event(input))) - }) - .filter_map(future::ready); + let reaction = stream::select_all([ + stream::once(server_task) + .map(InputEvent::ServerError) + .boxed_local(), + child_killed.map(InputEvent::BuilderKilled).boxed_local(), + builder_crate_fs_change + .map(InputEvent::FsChange) + .boxed_local(), + builder_started + .map(InputEvent::BuilderStarted) + .boxed_local(), + browser_launch.map(InputEvent::BrowserOpened).boxed_local(), + ]) + .scan(self, move |app, input| { + future::ready(Some(app.input_event(input))) + }) + .filter_map(future::ready); - let mut output = initial.chain(reaction); + let mut output = initial.chain(reaction); - let (mut kill_child_sender, kill_child) = mpsc::channel(1); - let (mut run_builder_sender, run_builder) = mpsc::channel(1); - let (mut error_sender, error) = mpsc::channel(1); - let (mut stderr_sender, stderr) = mpsc::channel(1); - let (mut open_browser_sender, open_browser) = mpsc::channel(1); + let (mut kill_child_sender, kill_child) = mpsc::channel(1); + let (mut run_builder_sender, run_builder) = mpsc::channel(1); + let (mut error_sender, error) = mpsc::channel(1); + let (mut stderr_sender, stderr) = mpsc::channel(1); + let (mut open_browser_sender, open_browser) = mpsc::channel(1); - let stream_splitter_task = async move { - loop { - let event = output.next().await.unwrap(); - match event { - OutputEvent::Stderr(output) => { - stderr_sender.send(output).await.unwrap(); - } - OutputEvent::RunBuilder => { - run_builder_sender.send(()).await.unwrap(); - } - OutputEvent::KillChildProcess(child) => { - kill_child_sender.send(child).await.unwrap(); - } - OutputEvent::Error(error) => { - error_sender.send(error).await.unwrap(); - } - OutputEvent::OpenBrowser => { - open_browser_sender.send(()).await.unwrap(); + let stream_splitter_task = async move { + loop { + let event = output.next().await.unwrap(); + match event { + OutputEvent::Stderr(output) => { + stderr_sender.send(output).await.unwrap(); + } + OutputEvent::RunBuilder => { + run_builder_sender.send(()).await.unwrap(); + } + OutputEvent::KillChildProcess(child) => { + kill_child_sender.send(child).await.unwrap(); + } + OutputEvent::Error(error) => { + error_sender.send(error).await.unwrap(); + } + OutputEvent::OpenBrowser => { + open_browser_sender.send(()).await.unwrap(); + } } } } - } - .boxed_local(); - - let error = error - .into_future() - .map(|(error, _tail_of_stream)| error.unwrap()) .boxed_local(); - Outputs { - stderr: stderr.boxed_local(), - kill_child: kill_child.boxed_local(), - run_builder: run_builder.boxed_local(), - open_browser: open_browser.boxed_local(), - error, - stream_splitter_task, + let error = error + .into_future() + .map(|(error, _tail_of_stream)| error.unwrap()) + .boxed_local(); + + Outputs { + stderr: stderr.boxed_local(), + kill_child: kill_child.boxed_local(), + run_builder: run_builder.boxed_local(), + open_browser: open_browser.boxed_local(), + error, + stream_splitter_task, + } } } diff --git a/ssg-parent/src/dev/app/state.rs b/ssg-parent/src/dev/app/state.rs index 73f1bf57..8ffaa9f0 100644 --- a/ssg-parent/src/dev/app/state.rs +++ b/ssg-parent/src/dev/app/state.rs @@ -1,9 +1,4 @@ -#[derive(Debug, Default)] -pub(super) struct State { - builder: BuilderState, -} - -impl State { +impl super::App { pub(super) fn input_event(&mut self, input: super::InputEvent) -> Option { match input { super::InputEvent::BuilderKilled(result) => self.builder_killed(result), @@ -92,7 +87,7 @@ impl State { } #[derive(Debug, Default)] -enum BuilderState { +pub(super) enum BuilderState { // this exists to ensure that only one child is live at a time AwaitingKillResult, #[default]