watchexec/lib/src/action/outcome.rs

86 lines
2.5 KiB
Rust
Raw Normal View History

use crate::signal::process::SubSignal;
2021-09-18 07:20:05 +02:00
2021-10-16 14:12:04 +02:00
/// The outcome to execute when an action is triggered.
///
/// Logic against the state of the command should be expressed using these variants, rather than
/// inside the action handler, as it ensures the state of the command is always the latest available
/// when the outcome is executed.
2021-09-18 07:20:05 +02:00
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Outcome {
/// Stop processing this action silently.
DoNothing,
/// If the command is running, stop it.
2021-10-16 14:12:04 +02:00
///
/// This should be used with an `IfRunning`, and will warn if the command is not running.
2021-09-18 07:20:05 +02:00
Stop,
/// If the command isn't running, start it.
2021-10-16 14:12:04 +02:00
///
/// This should be used with an `IfRunning`, and will warn if the command is running.
2021-09-18 07:20:05 +02:00
Start,
/// Wait for command completion.
2021-10-16 14:12:04 +02:00
///
/// Does nothing if the command isn't running.
2021-09-18 07:20:05 +02:00
Wait,
/// Send this signal to the command.
2021-10-16 14:12:04 +02:00
///
/// This does not wait for the command to complete.
Signal(SubSignal),
2021-09-18 07:20:05 +02:00
/// Clear the (terminal) screen.
Clear,
/// Reset the (terminal) screen.
///
/// This invokes (in order): [`WindowsCooked`][ClearScreen::WindowsCooked],
/// [`WindowsVt`][ClearScreen::WindowsVt], [`VtLeaveAlt`][ClearScreen::VtLeaveAlt],
2021-10-16 14:12:04 +02:00
/// [`VtWellDone`][ClearScreen::VtWellDone], and [the default clear][ClearScreen::default()].
2021-09-18 07:20:05 +02:00
Reset,
/// Exit watchexec.
Exit,
/// When command is running, do the first, otherwise the second.
IfRunning(Box<Outcome>, Box<Outcome>),
/// Do both outcomes in order.
Both(Box<Outcome>, Box<Outcome>),
}
impl Default for Outcome {
fn default() -> Self {
Self::DoNothing
}
}
impl Outcome {
2021-10-16 14:12:04 +02:00
/// Convenience function to create an outcome conditional on the state of the subprocess.
2021-09-18 07:20:05 +02:00
pub fn if_running(then: Outcome, otherwise: Outcome) -> Self {
Self::IfRunning(Box::new(then), Box::new(otherwise))
}
2021-10-16 14:12:04 +02:00
/// Convenience function to create a sequence of outcomes.
2021-09-18 07:20:05 +02:00
pub fn both(one: Outcome, two: Outcome) -> Self {
Self::Both(Box::new(one), Box::new(two))
}
2021-10-16 14:12:04 +02:00
/// Convenience function to wait for the subprocess to complete before executing the outcome.
2021-09-18 07:20:05 +02:00
pub fn wait(and_then: Outcome) -> Self {
Self::Both(Box::new(Outcome::Wait), Box::new(and_then))
}
2021-10-16 14:12:04 +02:00
/// Resolves the outcome given the current state of the subprocess.
2021-09-18 07:20:05 +02:00
pub fn resolve(self, is_running: bool) -> Self {
match (is_running, self) {
(true, Self::IfRunning(then, _)) => then.resolve(true),
(false, Self::IfRunning(_, otherwise)) => otherwise.resolve(false),
(ir, Self::Both(one, two)) => Self::both(one.resolve(ir), two.resolve(ir)),
(_, other) => other,
}
}
}