spry 0.0.4

Resilient, self-healing async process hierarchies in the style of Erlang/OTP
Documentation
//! Marker types used to indicate the lifecycle policy of a child process
//!
//! Note that these types are not at present user-definable.

use crate::internal::{ConcretePolicy, Policy, ProcessOutcome};

/// A permanent child is expected to run indefinitely. If it terminates for any reason this will
/// trigger a restart of its parent system, and it will itself be restarted.
pub struct Permanent;

impl<R> Policy<R> for Permanent {
  type Output = R;

  fn concrete() -> ConcretePolicy {
    ConcretePolicy::Permanent
  }

  fn should_skip(_: Option<&ProcessOutcome>) -> bool {
    false
  }

  fn output(value: R) -> Self::Output {
    value
  }

  fn fail() -> Self::Output {
    panic!("unreachable")
  }
}

/// A transient child is expected to run and then eventually terminate normally. If it panics then
/// it will trigger a restart of its parent system, and it will itself be restarted.
pub struct Transient;

impl<R> Policy<R> for Transient {
  type Output = Option<R>;

  fn concrete() -> ConcretePolicy {
    ConcretePolicy::Transient
  }

  fn should_skip(outcome: Option<&ProcessOutcome>) -> bool {
    // transient processes are only restarted if they fail (or are new and thus aren't being restarted)
    !matches!(outcome, None | Some(ProcessOutcome::Panicked))
  }

  fn output(value: R) -> Self::Output {
    Some(value)
  }

  fn fail() -> Self::Output {
    None
  }
}

/// A temporary child may terminate for any reason without causing a restart. It is never restarted,
/// even if it is terminated due to the failure of a sibling process.
pub struct Temporary;

impl<R> Policy<R> for Temporary {
  type Output = Option<R>;

  fn concrete() -> ConcretePolicy {
    ConcretePolicy::Temporary
  }

  fn should_skip(outcome: Option<&ProcessOutcome>) -> bool {
    // temporary processes are never restarted
    outcome.is_some()
  }

  fn output(value: R) -> Self::Output {
    Some(value)
  }

  fn fail() -> Self::Output {
    None
  }
}