use crate::{
schedule::OrdinaryDirective,
snapshot::{TimerCompletion, TimerCompletionOutcome},
};
use std::time::Duration;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OnceDecision {
Stop,
ContinueImmediately,
RetryAfter(Duration),
ScheduleAt(u64),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum AfterCompletionDecision {
Stop,
ContinueImmediately,
RetryAfter(Duration),
ScheduleAt(u64),
RecurAfterCompletion,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct OnceRunResult {
completion: TimerCompletion,
decision: OnceDecision,
}
impl OnceRunResult {
#[must_use]
pub const fn new(completion: TimerCompletion, decision: OnceDecision) -> Self {
Self {
decision: if matches!(
completion.outcome(),
TimerCompletionOutcome::InvariantFailure
) {
OnceDecision::Stop
} else {
decision
},
completion,
}
}
#[must_use]
pub const fn completion(self) -> TimerCompletion {
self.completion
}
#[must_use]
pub const fn decision(self) -> OnceDecision {
self.decision
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AfterCompletionRunResult {
completion: TimerCompletion,
decision: AfterCompletionDecision,
}
impl AfterCompletionRunResult {
#[must_use]
pub const fn new(completion: TimerCompletion, decision: AfterCompletionDecision) -> Self {
Self {
decision: if matches!(
completion.outcome(),
TimerCompletionOutcome::InvariantFailure
) {
AfterCompletionDecision::Stop
} else {
decision
},
completion,
}
}
#[must_use]
pub const fn completion(self) -> TimerCompletion {
self.completion
}
#[must_use]
pub const fn decision(self) -> AfterCompletionDecision {
self.decision
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct OrdinaryRunResult {
completion: TimerCompletion,
directive: OrdinaryDirective,
}
impl OrdinaryRunResult {
pub(super) const fn new(completion: TimerCompletion, directive: OrdinaryDirective) -> Self {
Self {
directive: if matches!(
completion.outcome(),
TimerCompletionOutcome::InvariantFailure
) {
OrdinaryDirective::Stop
} else {
directive
},
completion,
}
}
pub(super) const fn completion(self) -> TimerCompletion {
self.completion
}
pub(super) const fn directive(self) -> OrdinaryDirective {
self.directive
}
}
impl From<OnceDecision> for OrdinaryDirective {
fn from(value: OnceDecision) -> Self {
match value {
OnceDecision::Stop => Self::Stop,
OnceDecision::ContinueImmediately => Self::ContinueImmediately,
OnceDecision::RetryAfter(delay) => Self::RetryAfter(delay),
OnceDecision::ScheduleAt(deadline) => Self::ScheduleAt(deadline),
}
}
}
impl From<AfterCompletionDecision> for OrdinaryDirective {
fn from(value: AfterCompletionDecision) -> Self {
match value {
AfterCompletionDecision::Stop => Self::Stop,
AfterCompletionDecision::ContinueImmediately => Self::ContinueImmediately,
AfterCompletionDecision::RetryAfter(delay) => Self::RetryAfter(delay),
AfterCompletionDecision::ScheduleAt(deadline) => Self::ScheduleAt(deadline),
AfterCompletionDecision::RecurAfterCompletion => Self::RecurAfterCompletion,
}
}
}
impl From<OnceRunResult> for OrdinaryRunResult {
fn from(value: OnceRunResult) -> Self {
Self {
completion: value.completion,
directive: value.decision.into(),
}
}
}
impl From<AfterCompletionRunResult> for OrdinaryRunResult {
fn from(value: AfterCompletionRunResult) -> Self {
Self {
completion: value.completion,
directive: value.decision.into(),
}
}
}
#[cfg(test)]
mod tests;