use crate::effects::Effect;
use std::thread::ThreadId;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum EffectIsolationLevel {
Complete,
SideEffectOnly,
WriteOnly,
Custom(EffectIsolationRules),
}
#[derive(Debug, Clone)]
pub struct EffectIsolationRules {
pub allowed_effects: Vec<Effect>,
pub blocked_effects: Vec<Effect>,
pub custom_validator: Option<fn(&Effect, ThreadId, ThreadId) -> bool>,
pub exceptions: Vec<IsolationException>,
}
#[derive(Debug, Clone)]
pub struct IsolationException {
pub effect: Effect,
pub threads: Vec<ThreadId>,
pub condition: String,
}
impl Default for EffectIsolationRules {
fn default() -> Self {
Self {
allowed_effects: vec![Effect::Pure],
blocked_effects: vec![Effect::IO, Effect::State],
custom_validator: None,
exceptions: Vec::new(),
}
}
}
impl EffectIsolationRules {
pub fn allows_effect(&self, effect: &Effect, _source: ThreadId, _target: ThreadId) -> bool {
if self.blocked_effects.contains(effect) {
return false;
}
if self.allowed_effects.contains(effect) {
return true;
}
if let Some(validator) = self.custom_validator {
return validator(effect, _source, _target);
}
false
}
pub fn add_exception(&mut self, exception: IsolationException) {
self.exceptions.push(exception);
}
}
impl PartialEq for EffectIsolationRules {
fn eq(&self, other: &Self) -> bool {
self.allowed_effects == other.allowed_effects &&
self.blocked_effects == other.blocked_effects &&
self.exceptions == other.exceptions
}
}
impl Eq for EffectIsolationRules {}
impl std::hash::Hash for EffectIsolationRules {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.allowed_effects.hash(state);
self.blocked_effects.hash(state);
self.exceptions.hash(state);
}
}
impl PartialEq for IsolationException {
fn eq(&self, other: &Self) -> bool {
self.effect == other.effect &&
self.threads == other.threads &&
self.condition == other.condition
}
}
impl Eq for IsolationException {}
impl std::hash::Hash for IsolationException {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.effect.hash(state);
self.threads.hash(state);
self.condition.hash(state);
}
}