diff --git a/lib/examples/demo.rs b/lib/examples/demo.rs new file mode 100644 index 0000000..56566f0 --- /dev/null +++ b/lib/examples/demo.rs @@ -0,0 +1,67 @@ +use watchexec::{ + action::{Action, Outcome}, + config::{InitConfigBuilder, RuntimeConfig}, + error::ReconfigError, + fs::Watcher, + signal::Signal, + Watchexec, +}; + +// Run with: `env RUST_LOG=debug cargo run --example print_out` +#[tokio::main] +async fn main() -> color_eyre::eyre::Result<()> { + tracing_subscriber::fmt::init(); + color_eyre::install()?; + + let mut init = InitConfigBuilder::default(); + init.on_error(|err| async move { + eprintln!("Watchexec Runtime Error: {}", err); + Ok::<(), std::convert::Infallible>(()) + }); + + let mut runtime = RuntimeConfig::default(); + runtime.pathset(["src"]); + runtime.command(["date"]); + + let wx = Watchexec::new(init.build()?, runtime.clone())?; + let w = wx.clone(); + + let config = runtime.clone(); + runtime.on_action(move |action: Action| { + let mut config = config.clone(); + let w = w.clone(); + async move { + eprintln!("Watchexec Action: {:?}", action); + + let sigs = action + .events + .iter() + .flat_map(|event| event.signals()) + .collect::>(); + + if sigs.iter().any(|sig| sig == &Signal::Interrupt) { + action.outcome(Outcome::Exit); + } else if sigs.iter().any(|sig| sig == &Signal::User1) { + eprintln!("Switching to native for funsies"); + config.file_watcher(Watcher::Native).keep_action(); + w.reconfigure(config)?; + } else if sigs.iter().any(|sig| sig == &Signal::User2) { + eprintln!("Switching to polling for funsies"); + config.file_watcher(Watcher::Poll).keep_action(); + w.reconfigure(config)?; + } else { + action.outcome(Outcome::if_running( + Outcome::both(Outcome::Stop, Outcome::Start), + Outcome::Start, + )); + } + + Ok::<(), ReconfigError>(()) + } + }); + + wx.reconfigure(runtime)?; + wx.main().await??; + + Ok(()) +} diff --git a/lib/examples/print_out.rs b/lib/examples/print_out.rs deleted file mode 100644 index a86d8bf..0000000 --- a/lib/examples/print_out.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::convert::Infallible; - -use watchexec::{ - action::{Action, Outcome}, - config::{InitConfigBuilder, RuntimeConfig}, - signal::Signal, - Watchexec, -}; - -// Run with: `env RUST_LOG=debug cargo run --example print_out` -#[tokio::main] -async fn main() -> color_eyre::eyre::Result<()> { - tracing_subscriber::fmt::init(); - color_eyre::install()?; - - let mut init = InitConfigBuilder::default(); - init.on_error(|err| async move { - eprintln!("Watchexec Runtime Error: {}", err); - Ok::<(), std::convert::Infallible>(()) - }); - - let mut runtime = RuntimeConfig::default(); - runtime.pathset(["src"]); - runtime.command(["date"]); - runtime.on_action(|action: Action| async move { - eprintln!("Watchexec Action: {:?}", action); - - if action - .events - .iter() - .flat_map(|event| event.signals()) - .any(|sig| sig == Signal::Interrupt) - { - action.outcome(Outcome::Exit); - } else { - action.outcome(Outcome::if_running( - Outcome::both(Outcome::Stop, Outcome::Start), - Outcome::Start, - )); - } - - Ok::<(), Infallible>(()) - }); - - let wx = Watchexec::new(init.build()?, runtime)?; - wx.main().await??; - - Ok(()) -} diff --git a/lib/src/config.rs b/lib/src/config.rs index 21cbb40..4a1c128 100644 --- a/lib/src/config.rs +++ b/lib/src/config.rs @@ -78,6 +78,16 @@ impl RuntimeConfig { self.action.action_handler = Arc::new(AtomicTake::new(Box::new(handler) as _)); self } + + /// Keep the action handler the same. + /// + /// This is especially useful when reconfiguring _within_ the action handler. + /// + /// Passing this config to `Watchexec::new()` will cause a `CriticalError::MissingHandler`. + pub fn keep_action(&mut self) -> &mut Self { + self.action.action_handler = Arc::new(AtomicTake::empty()); + self + } } /// Initialisation configuration for [`Watchexec`][crate::Watchexec].