use crate::error::FsError;
use crate::path::Path;
use crate::temp::PersistFailureState;
use crate::temp::TempResourceState;
#[derive(Clone)]
pub(crate) struct TempLifecycle {
state: TempResourceState,
failure_state: PersistFailureState,
publication_target: Option<Path>,
}
impl TempLifecycle {
#[inline]
pub(crate) const fn new() -> Self {
Self {
state: TempResourceState::Owned,
failure_state: PersistFailureState::NotPublished,
publication_target: None,
}
}
#[inline]
pub(crate) const fn state(&self) -> TempResourceState {
self.state
}
#[inline]
pub(crate) const fn failure_state(&self) -> PersistFailureState {
self.failure_state
}
#[inline]
pub(crate) fn publication_target(&self) -> Option<&Path> {
self.publication_target.as_ref()
}
#[cfg(feature = "async")]
#[inline]
pub(crate) fn begin_pending(&mut self) {
self.state = TempResourceState::Indeterminate;
self.failure_state = PersistFailureState::Indeterminate;
}
#[inline]
pub(crate) fn record_success(&mut self, kept: bool, target: Path) {
self.state = if kept {
TempResourceState::Kept
} else {
TempResourceState::Persisted
};
self.failure_state = PersistFailureState::PublishedSourceReleased;
self.publication_target = Some(target);
}
#[inline]
pub(crate) fn record_failure(&mut self, state: PersistFailureState, target: Option<Path>, kept: bool) {
if matches!(
state,
PersistFailureState::PublishedSourceRetained
| PersistFailureState::PublishedSourceReleased
| PersistFailureState::PublishedSourceIndeterminate
) && let Some(target) = target
{
self.publication_target = Some(target);
}
self.failure_state = state;
self.state = match state {
PersistFailureState::NotPublished => TempResourceState::Owned,
PersistFailureState::NotPublishedSourceReleased => TempResourceState::Cleaned,
PersistFailureState::PublishedSourceRetained | PersistFailureState::NotPublishedSourceCleanupRequired => {
TempResourceState::CleanupRequired
}
PersistFailureState::PublishedSourceReleased => {
if kept {
TempResourceState::Kept
} else {
TempResourceState::Persisted
}
}
PersistFailureState::Indeterminate
| PersistFailureState::NotPublishedSourceIndeterminate
| PersistFailureState::PublishedSourceIndeterminate => TempResourceState::Indeterminate,
};
}
#[inline]
pub(crate) fn record_cleanup_success(&mut self) {
self.state = TempResourceState::Cleaned;
if self.publication_target.is_some() {
self.failure_state = PersistFailureState::PublishedSourceReleased;
return;
}
self.failure_state = match self.failure_state {
PersistFailureState::PublishedSourceRetained
| PersistFailureState::PublishedSourceReleased
| PersistFailureState::PublishedSourceIndeterminate => PersistFailureState::PublishedSourceReleased,
PersistFailureState::Indeterminate => PersistFailureState::Indeterminate,
_ => PersistFailureState::NotPublishedSourceReleased,
};
}
#[inline]
pub(crate) fn record_cleanup_error(&mut self, error: &FsError) {
if self.state == TempResourceState::Indeterminate {
return;
}
if error.has_indeterminate_effect() {
self.state = TempResourceState::Indeterminate;
self.failure_state = if self.publication_target.is_some()
|| matches!(
self.failure_state,
PersistFailureState::PublishedSourceRetained | PersistFailureState::PublishedSourceReleased
) {
PersistFailureState::PublishedSourceIndeterminate
} else {
PersistFailureState::NotPublishedSourceIndeterminate
};
} else {
self.state = TempResourceState::CleanupRequired;
if self.failure_state == PersistFailureState::NotPublished {
self.failure_state = PersistFailureState::NotPublishedSourceCleanupRequired;
}
}
}
}