// @generated — Generated by `cargo xtask machine-codegen --all`.
#![allow(
    clippy::unwrap_used,
    clippy::expect_used,
    clippy::panic,
    clippy::implicit_clone,
    clippy::unnecessary_cast,
    clippy::redundant_clone,
    clippy::zero_sized_map_values
)]

pub fn schema() -> meerkat_machine_schema::MachineSchema {
    meerkat_machine_schema::catalog::dsl::dsl_approval_lifecycle_machine()
}

#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum ApprovalLifecycleDecision {
    #[default]
    #[serde(rename = "Approve")]
    Approve,
    #[serde(rename = "Deny")]
    Deny,
}
impl ApprovalLifecycleDecision {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Approve => "Approve",
            Self::Deny => "Deny",
        }
    }
}
impl std::convert::TryFrom<&str> for ApprovalLifecycleDecision {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "Approve" => Ok(Self::Approve),
            "Deny" => Ok(Self::Deny),
            other => Err(format!("invalid ApprovalLifecycleDecision value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for ApprovalLifecycleDecision {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for ApprovalLifecycleDecision {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}
#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum ApprovalLifecycleRejectionReason {
    #[default]
    #[serde(rename = "NotFound")]
    NotFound,
    #[serde(rename = "AlreadyExists")]
    AlreadyExists,
    #[serde(rename = "AlreadyDecided")]
    AlreadyDecided,
    #[serde(rename = "Expired")]
    Expired,
    #[serde(rename = "InvalidDecision")]
    InvalidDecision,
    #[serde(rename = "EmptyAllowedDecisions")]
    EmptyAllowedDecisions,
    #[serde(rename = "InvalidRestoredRecord")]
    InvalidRestoredRecord,
}
impl ApprovalLifecycleRejectionReason {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::NotFound => "NotFound",
            Self::AlreadyExists => "AlreadyExists",
            Self::AlreadyDecided => "AlreadyDecided",
            Self::Expired => "Expired",
            Self::InvalidDecision => "InvalidDecision",
            Self::EmptyAllowedDecisions => "EmptyAllowedDecisions",
            Self::InvalidRestoredRecord => "InvalidRestoredRecord",
        }
    }
}
impl std::convert::TryFrom<&str> for ApprovalLifecycleRejectionReason {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "NotFound" => Ok(Self::NotFound),
            "AlreadyExists" => Ok(Self::AlreadyExists),
            "AlreadyDecided" => Ok(Self::AlreadyDecided),
            "Expired" => Ok(Self::Expired),
            "InvalidDecision" => Ok(Self::InvalidDecision),
            "EmptyAllowedDecisions" => Ok(Self::EmptyAllowedDecisions),
            "InvalidRestoredRecord" => Ok(Self::InvalidRestoredRecord),
            other => Err(format!(
                "invalid ApprovalLifecycleRejectionReason value `{other}`"
            )),
        }
    }
}
impl std::convert::TryFrom<String> for ApprovalLifecycleRejectionReason {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for ApprovalLifecycleRejectionReason {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}
#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum ApprovalLifecycleStatus {
    #[default]
    #[serde(rename = "Pending")]
    Pending,
    #[serde(rename = "Approved")]
    Approved,
    #[serde(rename = "Denied")]
    Denied,
    #[serde(rename = "Expired")]
    Expired,
    #[serde(rename = "Cancelled")]
    Cancelled,
}
impl ApprovalLifecycleStatus {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Pending => "Pending",
            Self::Approved => "Approved",
            Self::Denied => "Denied",
            Self::Expired => "Expired",
            Self::Cancelled => "Cancelled",
        }
    }
}
impl std::convert::TryFrom<&str> for ApprovalLifecycleStatus {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "Pending" => Ok(Self::Pending),
            "Approved" => Ok(Self::Approved),
            "Denied" => Ok(Self::Denied),
            "Expired" => Ok(Self::Expired),
            "Cancelled" => Ok(Self::Cancelled),
            other => Err(format!("invalid ApprovalLifecycleStatus value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for ApprovalLifecycleStatus {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for ApprovalLifecycleStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}

pub trait Context {}
pub struct EmptyContext;
impl Context for EmptyContext {}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Phase {
    Ready,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct State {
    pub phase: Phase,
    pub approval_ids: std::collections::BTreeSet<String>,
    pub approval_statuses: std::collections::BTreeMap<String, ApprovalLifecycleStatus>,
    pub approval_approve_allowed: std::collections::BTreeMap<String, bool>,
    pub approval_deny_allowed: std::collections::BTreeMap<String, bool>,
    pub approval_has_expiry: std::collections::BTreeMap<String, bool>,
}
impl Default for State {
    fn default() -> Self {
        initial_state()
    }
}

pub mod inputs {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct CreateApproval {
        pub approval_id: String,
        pub approve_allowed: bool,
        pub deny_allowed: bool,
        pub has_expiry: bool,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct RestoreApproval {
        pub approval_id: String,
        pub status: ApprovalLifecycleStatus,
        pub approve_allowed: bool,
        pub deny_allowed: bool,
        pub has_expiry: bool,
        pub decision: Option<ApprovalLifecycleDecision>,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct ObserveApprovalExpiry {
        pub approval_id: String,
        pub expired: bool,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct DecideApproval {
        pub approval_id: String,
        pub decision: ApprovalLifecycleDecision,
    }
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Input {
    CreateApproval(inputs::CreateApproval),
    RestoreApproval(inputs::RestoreApproval),
    ObserveApprovalExpiry(inputs::ObserveApprovalExpiry),
    DecideApproval(inputs::DecideApproval),
}
impl Input {
    pub fn kind(&self) -> InputKind {
        match self {
            Self::CreateApproval(_) => InputKind::CreateApproval,
            Self::RestoreApproval(_) => InputKind::RestoreApproval,
            Self::ObserveApprovalExpiry(_) => InputKind::ObserveApprovalExpiry,
            Self::DecideApproval(_) => InputKind::DecideApproval,
        }
    }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum InputKind {
    CreateApproval,
    RestoreApproval,
    ObserveApprovalExpiry,
    DecideApproval,
}

pub mod effects {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct ApprovalStatusResolved {
        pub approval_id: String,
        pub status: ApprovalLifecycleStatus,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct ApprovalLifecycleRejected {
        pub approval_id: String,
        pub reason: ApprovalLifecycleRejectionReason,
    }
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Effect {
    ApprovalStatusResolved(effects::ApprovalStatusResolved),
    ApprovalLifecycleRejected(effects::ApprovalLifecycleRejected),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum EffectKind {
    ApprovalStatusResolved,
    ApprovalLifecycleRejected,
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionId {
    CreateRejectedEmptyAllowedDecisions,
    CreateRejectedAlreadyExists,
    CreatePending,
    RestoreRejectedDuplicate,
    RestoreRejectedEmptyAllowedDecisions,
    RestorePending,
    RestoreExpired,
    RestoreCancelled,
    RestoreApproved,
    RestoreDenied,
    RestoreRejectedInvalidRecord,
    ObserveExpiryRejectedMissing,
    ObserveExpiryExpiresPending,
    ObserveExpiryPendingNoop,
    ObserveExpiryApprovedNoop,
    ObserveExpiryDeniedNoop,
    ObserveExpiryExpiredNoop,
    ObserveExpiryCancelledNoop,
    DecideRejectedMissing,
    DecideRejectedExpired,
    DecideRejectedAlreadyDecided,
    DecideRejectedApproveNotAllowed,
    DecideRejectedDenyNotAllowed,
    DecideApprove,
    DecideDeny,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum GuardId {
    None,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum HelperId {
    None,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct GuardRejection {
    pub transition_id: TransitionId,
    pub guard_id: GuardId,
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TriggerDiscriminant {
    Input(InputKind),
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionRefusal {
    NoMatchingTransition {
        phase: Phase,
        trigger: TriggerDiscriminant,
    },
    GuardRejected {
        rejections: Vec<GuardRejection>,
    },
    AmbiguousTransition {
        transitions: Vec<TransitionId>,
    },
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum KernelError {
    ContextViolation {
        transition_id: TransitionId,
        detail: String,
    },
    HelperEvaluation {
        helper_id: HelperId,
        detail: String,
    },
    CodegenInvariant {
        detail: String,
    },
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionError {
    Refusal(TransitionRefusal),
    Kernel(KernelError),
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct Outcome {
    pub transition_id: TransitionId,
    pub next_state: State,
    pub effects: Vec<Effect>,
}

pub mod helpers {
    #[allow(unused_imports)]
    use super::*;
    pub fn none<C: Context>(_: &State, context: &C) -> Result<(), KernelError> {
        let _ = context;
        Ok(())
    }
}

pub fn initial_state() -> State {
    State {
        phase: Phase::Ready,
        approval_ids: Default::default(),
        approval_statuses: Default::default(),
        approval_approve_allowed: Default::default(),
        approval_deny_allowed: Default::default(),
        approval_has_expiry: Default::default(),
    }
}
