#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContractViolation {
code: &'static str,
detail: String,
}
impl ContractViolation {
pub fn new(code: &'static str, detail: impl Into<String>) -> Self {
Self {
code,
detail: detail.into(),
}
}
pub fn code(&self) -> &'static str {
self.code
}
pub fn detail(&self) -> &str {
&self.detail
}
}
impl std::fmt::Display for ContractViolation {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
formatter,
"saga contract violation [{}]: {}",
self.code, self.detail
)
}
}
impl std::error::Error for ContractViolation {}
pub type ContractResult<T> = Result<T, ContractViolation>;
pub const CODE_IDENTIFIER_EMPTY: &str = "identifier_empty";
pub const CODE_IDENTIFIER_UNTRIMMED: &str = "identifier_untrimmed";
pub const CODE_IDENTIFIER_TOO_LONG: &str = "identifier_too_long";
pub const CODE_IDENTIFIER_CHARSET: &str = "identifier_charset";
pub const CODE_COUNTER_ZERO: &str = "counter_must_start_at_one";
pub const CODE_COUNTER_OVERFLOW: &str = "counter_overflow";
pub const CODE_DEFINITION_EMPTY: &str = "definition_has_no_step";
pub const CODE_DEFINITION_DUPLICATE_STEP: &str = "definition_duplicate_step";
pub const CODE_DEFINITION_PIVOT_NOT_LAST: &str = "definition_pivot_not_last";
pub const CODE_DEFINITION_RESOLUTION_MISSING: &str = "definition_resolution_missing";
pub const CODE_DEFINITION_MODE_CONFLICT: &str = "definition_mode_conflict";
pub const CODE_DEFINITION_BUDGET_ZERO: &str = "definition_budget_zero";
pub const CODE_TRANSITION_ILLEGAL: &str = "transition_illegal";
pub const CODE_TRANSITION_FORWARD_AFTER_COMPENSATION: &str =
"transition_forward_after_compensation";
pub const CODE_PLAN_SUCCEEDED_PIVOT: &str = "plan_contains_succeeded_pivot";
pub const CODE_PLAN_UNKNOWN_STEP: &str = "plan_unknown_step";
pub const CODE_PLAN_DUPLICATE_STEP: &str = "plan_duplicate_step";
pub const CODE_PLAN_MISSING_STEP: &str = "plan_missing_step";
pub const CODE_PLAN_UNSETTLED_STEP: &str = "plan_unsettled_step";