use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
pub enum IsolationLevel {
ReadUncommitted = 1,
ReadCommitted = 2,
RepeatableRead = 3,
Serializable = 4,
#[default]
Default = 0,
}
impl IsolationLevel {
pub fn from_value(value: i32) -> Option<Self> {
match value {
0 => Some(IsolationLevel::Default),
1 => Some(IsolationLevel::ReadUncommitted),
2 => Some(IsolationLevel::ReadCommitted),
3 => Some(IsolationLevel::RepeatableRead),
4 => Some(IsolationLevel::Serializable),
_ => None,
}
}
pub fn value(&self) -> i32 {
*self as i32
}
pub fn is_default(&self) -> bool {
matches!(self, IsolationLevel::Default)
}
pub fn description(&self) -> &'static str {
match self {
IsolationLevel::ReadUncommitted => "Read Uncommitted - allows dirty reads",
IsolationLevel::ReadCommitted => "Read Committed - prevents dirty reads",
IsolationLevel::RepeatableRead => {
"Repeatable Read - prevents dirty and non-repeatable reads"
},
IsolationLevel::Serializable => "Serializable - full isolation",
IsolationLevel::Default => "Default - uses database default",
}
}
}
impl std::fmt::Display for IsolationLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IsolationLevel::ReadUncommitted => write!(f, "READ_UNCOMMITTED"),
IsolationLevel::ReadCommitted => write!(f, "READ_COMMITTED"),
IsolationLevel::RepeatableRead => write!(f, "REPEATABLE_READ"),
IsolationLevel::Serializable => write!(f, "SERIALIZABLE"),
IsolationLevel::Default => write!(f, "DEFAULT"),
}
}
}
impl std::str::FromStr for IsolationLevel {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_uppercase().as_str() {
"READ_UNCOMMITTED" | "READ-UNCOMMITTED" => Ok(IsolationLevel::ReadUncommitted),
"READ_COMMITTED" | "READ-COMMITTED" => Ok(IsolationLevel::ReadCommitted),
"REPEATABLE_READ" | "REPEATABLE-READ" => Ok(IsolationLevel::RepeatableRead),
"SERIALIZABLE" => Ok(IsolationLevel::Serializable),
"DEFAULT" => Ok(IsolationLevel::Default),
_ => Err(format!("Unknown isolation level: {}", s)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_isolation_from_str() {
assert_eq!("SERIALIZABLE".parse::<IsolationLevel>().unwrap(), IsolationLevel::Serializable);
assert_eq!(
"read_committed".parse::<IsolationLevel>().unwrap(),
IsolationLevel::ReadCommitted
);
}
#[test]
fn test_isolation_display() {
assert_eq!(IsolationLevel::Serializable.to_string(), "SERIALIZABLE");
assert_eq!(IsolationLevel::Default.to_string(), "DEFAULT");
}
}