use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
pub enum Propagation {
#[default]
Required = 0,
Supports = 1,
Mandatory = 2,
RequiresNew = 3,
NotSupported = 4,
Never = 5,
Nested = 6,
}
impl Propagation {
pub fn from_value(value: i32) -> Option<Self> {
match value {
0 => Some(Propagation::Required),
1 => Some(Propagation::Supports),
2 => Some(Propagation::Mandatory),
3 => Some(Propagation::RequiresNew),
4 => Some(Propagation::NotSupported),
5 => Some(Propagation::Never),
6 => Some(Propagation::Nested),
_ => None,
}
}
pub fn value(&self) -> i32 {
*self as i32
}
pub fn creates_new_transaction(&self) -> bool {
matches!(self, Propagation::Required | Propagation::RequiresNew | Propagation::Nested)
}
pub fn description(&self) -> &'static str {
match self {
Propagation::Required => "Support current transaction, create new if none",
Propagation::Supports => {
"Support current transaction, execute non-transactionally if none"
},
Propagation::Mandatory => "Support current transaction, error if none",
Propagation::RequiresNew => "Always create new transaction",
Propagation::NotSupported => "Execute non-transactionally, suspend current if exists",
Propagation::Never => "Execute non-transactionally, error if transaction exists",
Propagation::Nested => "Execute within nested transaction if one exists",
}
}
}
impl std::fmt::Display for Propagation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Propagation::Required => write!(f, "REQUIRED"),
Propagation::Supports => write!(f, "SUPPORTS"),
Propagation::Mandatory => write!(f, "MANDATORY"),
Propagation::RequiresNew => write!(f, "REQUIRES_NEW"),
Propagation::NotSupported => write!(f, "NOT_SUPPORTED"),
Propagation::Never => write!(f, "NEVER"),
Propagation::Nested => write!(f, "NESTED"),
}
}
}
impl std::str::FromStr for Propagation {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_uppercase().as_str() {
"REQUIRED" => Ok(Propagation::Required),
"SUPPORTS" => Ok(Propagation::Supports),
"MANDATORY" => Ok(Propagation::Mandatory),
"REQUIRES_NEW" | "REQUIRES-NEW" => Ok(Propagation::RequiresNew),
"NOT_SUPPORTED" | "NOT-SUPPORTED" => Ok(Propagation::NotSupported),
"NEVER" => Ok(Propagation::Never),
"NESTED" => Ok(Propagation::Nested),
_ => Err(format!("Unknown propagation: {}", s)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_propagation_from_str() {
assert_eq!("REQUIRES_NEW".parse::<Propagation>().unwrap(), Propagation::RequiresNew);
assert_eq!("mandatory".parse::<Propagation>().unwrap(), Propagation::Mandatory);
}
#[test]
fn test_creates_new_transaction() {
assert!(Propagation::Required.creates_new_transaction());
assert!(Propagation::RequiresNew.creates_new_transaction());
assert!(!Propagation::Supports.creates_new_transaction());
assert!(!Propagation::Never.creates_new_transaction());
}
}