#![allow(clippy::module_name_repetitions)]
use std::convert::TryFrom;
pub trait Status: std::fmt::Debug + std::fmt::Display + private::Sealed {
fn is_settled(&self) -> bool;
fn sentiment(&self) -> StatusSentiment;
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum StatusSentiment {
Positive,
Neutral,
Negative,
}
impl StatusSentiment {
#[must_use]
pub fn is_positive(self) -> bool {
self == Self::Positive
}
#[must_use]
pub fn is_neutral(self) -> bool {
self == Self::Neutral
}
#[must_use]
pub fn is_negative(self) -> bool {
self == Self::Negative
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, parse_display::Display, parse_display::FromStr)]
#[display(style = "SNAKE_CASE")]
pub enum ChangeSetStatus {
CreatePending,
CreateInProgress,
CreateComplete,
DeletePending,
DeleteInProgress,
DeleteComplete,
DeleteFailed,
Failed,
}
impl Status for ChangeSetStatus {
fn is_settled(&self) -> bool {
match self {
Self::CreatePending
| Self::CreateInProgress
| Self::DeletePending
| Self::DeleteInProgress => false,
Self::CreateComplete | Self::DeleteComplete | Self::DeleteFailed | Self::Failed => true,
}
}
fn sentiment(&self) -> StatusSentiment {
match self {
Self::CreateComplete | Self::DeleteComplete => StatusSentiment::Positive,
Self::CreatePending
| Self::CreateInProgress
| Self::DeletePending
| Self::DeleteInProgress => StatusSentiment::Neutral,
Self::DeleteFailed | Self::Failed => StatusSentiment::Negative,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, parse_display::Display, parse_display::FromStr)]
#[display(style = "SNAKE_CASE")]
pub enum StackStatus {
CreateInProgress,
CreateFailed,
CreateComplete,
RollbackInProgress,
RollbackFailed,
RollbackComplete,
DeleteInProgress,
DeleteFailed,
DeleteComplete,
UpdateInProgress,
UpdateCompleteCleanupInProgress,
UpdateComplete,
UpdateFailed,
UpdateRollbackInProgress,
UpdateRollbackFailed,
UpdateRollbackCompleteCleanupInProgress,
UpdateRollbackComplete,
ReviewInProgress,
ImportInProgress,
ImportComplete,
ImportRollbackInProgress,
ImportRollbackFailed,
ImportRollbackComplete,
}
impl Status for StackStatus {
fn is_settled(&self) -> bool {
match self {
Self::CreateInProgress
| Self::RollbackInProgress
| Self::DeleteInProgress
| Self::UpdateInProgress
| Self::UpdateCompleteCleanupInProgress
| Self::UpdateRollbackInProgress
| Self::UpdateRollbackCompleteCleanupInProgress
| Self::ReviewInProgress
| Self::ImportInProgress
| Self::ImportRollbackInProgress => false,
Self::CreateFailed
| Self::CreateComplete
| Self::RollbackFailed
| Self::RollbackComplete
| Self::DeleteFailed
| Self::DeleteComplete
| Self::UpdateComplete
| Self::UpdateFailed
| Self::UpdateRollbackFailed
| Self::UpdateRollbackComplete
| Self::ImportComplete
| Self::ImportRollbackFailed
| Self::ImportRollbackComplete => true,
}
}
fn sentiment(&self) -> StatusSentiment {
match self {
Self::CreateComplete
| Self::DeleteComplete
| Self::UpdateComplete
| Self::ImportComplete => StatusSentiment::Positive,
Self::CreateInProgress
| Self::DeleteInProgress
| Self::UpdateInProgress
| Self::UpdateCompleteCleanupInProgress
| Self::ReviewInProgress
| Self::ImportInProgress => StatusSentiment::Neutral,
Self::CreateFailed
| Self::RollbackInProgress
| Self::RollbackFailed
| Self::RollbackComplete
| Self::DeleteFailed
| Self::UpdateFailed
| Self::UpdateRollbackInProgress
| Self::UpdateRollbackFailed
| Self::UpdateRollbackCompleteCleanupInProgress
| Self::UpdateRollbackComplete
| Self::ImportRollbackInProgress
| Self::ImportRollbackFailed
| Self::ImportRollbackComplete => StatusSentiment::Negative,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, parse_display::Display, parse_display::FromStr)]
#[display(style = "SNAKE_CASE")]
pub enum BlockedStackStatus {
CreateFailed,
RollbackComplete,
RollbackFailed,
DeleteFailed,
UpdateFailed,
UpdateRollbackFailed,
}
impl TryFrom<StackStatus> for BlockedStackStatus {
type Error = StackStatus;
fn try_from(status: StackStatus) -> Result<Self, Self::Error> {
match status {
StackStatus::CreateFailed => Ok(Self::CreateFailed),
StackStatus::RollbackComplete => Ok(Self::RollbackComplete),
StackStatus::RollbackFailed => Ok(Self::RollbackFailed),
StackStatus::DeleteFailed => Ok(Self::DeleteFailed),
StackStatus::UpdateFailed => Ok(Self::UpdateFailed),
StackStatus::UpdateRollbackFailed => Ok(Self::UpdateRollbackFailed),
StackStatus::CreateInProgress
| StackStatus::CreateComplete
| StackStatus::DeleteComplete
| StackStatus::DeleteInProgress
| StackStatus::ReviewInProgress
| StackStatus::RollbackInProgress
| StackStatus::UpdateInProgress
| StackStatus::UpdateCompleteCleanupInProgress
| StackStatus::UpdateComplete
| StackStatus::UpdateRollbackInProgress
| StackStatus::UpdateRollbackCompleteCleanupInProgress
| StackStatus::UpdateRollbackComplete
| StackStatus::ImportInProgress
| StackStatus::ImportComplete
| StackStatus::ImportRollbackInProgress
| StackStatus::ImportRollbackFailed
| StackStatus::ImportRollbackComplete => Err(status),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, parse_display::Display, parse_display::FromStr)]
#[display(style = "SNAKE_CASE")]
pub enum ResourceStatus {
CreateInProgress,
CreateFailed,
CreateComplete,
DeleteInProgress,
DeleteFailed,
DeleteComplete,
DeleteSkipped,
UpdateInProgress,
UpdateFailed,
UpdateComplete,
ImportFailed,
ImportComplete,
ImportInProgress,
ImportRollbackInProgress,
ImportRollbackFailed,
ImportRollbackComplete,
}
impl Status for ResourceStatus {
fn is_settled(&self) -> bool {
match self {
Self::CreateInProgress
| Self::DeleteInProgress
| Self::UpdateInProgress
| Self::ImportInProgress
| Self::ImportRollbackInProgress => false,
Self::CreateFailed
| Self::CreateComplete
| Self::DeleteFailed
| Self::DeleteComplete
| Self::DeleteSkipped
| Self::UpdateFailed
| Self::UpdateComplete
| Self::ImportFailed
| Self::ImportComplete
| Self::ImportRollbackFailed
| Self::ImportRollbackComplete => true,
}
}
fn sentiment(&self) -> StatusSentiment {
match self {
Self::CreateComplete
| Self::DeleteComplete
| Self::UpdateComplete
| Self::ImportComplete => StatusSentiment::Positive,
Self::CreateInProgress
| Self::DeleteInProgress
| Self::DeleteSkipped
| Self::UpdateInProgress
| Self::ImportInProgress => StatusSentiment::Neutral,
Self::CreateFailed
| Self::DeleteFailed
| Self::UpdateFailed
| Self::ImportFailed
| Self::ImportRollbackInProgress
| Self::ImportRollbackFailed
| Self::ImportRollbackComplete => StatusSentiment::Negative,
}
}
}
mod private {
pub trait Sealed {}
impl Sealed for super::ChangeSetStatus {}
impl Sealed for super::StackStatus {}
impl Sealed for super::ResourceStatus {}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn stack_status() {
assert_eq!(
format!("{}", StackStatus::UpdateRollbackCompleteCleanupInProgress).as_str(),
"UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS"
);
assert_eq!(
"UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS".parse(),
Ok(StackStatus::UpdateRollbackCompleteCleanupInProgress)
);
assert!("oh no".parse::<StackStatus>().is_err());
}
#[test]
fn resource_status() {
assert_eq!(
format!("{}", ResourceStatus::ImportRollbackInProgress).as_str(),
"IMPORT_ROLLBACK_IN_PROGRESS"
);
assert_eq!(
"IMPORT_ROLLBACK_IN_PROGRESS".parse(),
Ok(ResourceStatus::ImportRollbackInProgress)
);
assert!("oh no".parse::<ResourceStatus>().is_err());
}
}