use crate::context::StatContext;
use crate::error::StatError;
use crate::numeric::StatValue;
use crate::stat_id::StatId;
use crate::transform::core::StatTransform;
use rustc_hash::FxHashMap;
pub struct ConditionalTransform {
condition: Box<dyn Fn(&StatContext) -> bool + Send + Sync>,
transform: Box<dyn StatTransform>,
description: String,
}
impl ConditionalTransform {
pub fn new<F>(
condition: F,
transform: Box<dyn StatTransform>,
description: impl Into<String>,
) -> Self
where
F: Fn(&StatContext) -> bool + Send + Sync + 'static,
{
Self {
condition: Box::new(condition),
transform,
description: description.into(),
}
}
}
impl StatTransform for ConditionalTransform {
fn depends_on(&self) -> Vec<StatId> {
self.transform.depends_on()
}
fn apply(
&self,
input: StatValue,
dependencies: &FxHashMap<StatId, StatValue>,
context: &StatContext,
) -> Result<StatValue, StatError> {
if (self.condition)(context) {
self.transform.apply(input, dependencies, context)
} else {
Ok(input)
}
}
fn description(&self) -> String {
self.description.clone()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::numeric::{StatNumeric, StatValue};
use crate::transform::standard::MultiplicativeTransform;
#[test]
fn test_conditional_transform_applied() {
let mut context = StatContext::new();
context.set("is_night", true);
let inner = Box::new(MultiplicativeTransform::new(2.0));
let transform = ConditionalTransform::new(
|ctx| ctx.get::<bool>("is_night").unwrap_or(false),
inner,
"night bonus",
);
let deps = FxHashMap::default();
let result = transform
.apply(StatValue::from_f64(10.0), &deps, &context)
.unwrap();
assert_eq!(result.to_f64(), 20.0);
}
#[test]
fn test_conditional_transform_ignored() {
let mut context = StatContext::new();
context.set("is_night", false);
let inner = Box::new(MultiplicativeTransform::new(2.0));
let transform = ConditionalTransform::new(
|ctx| ctx.get::<bool>("is_night").unwrap_or(false),
inner,
"night bonus",
);
let deps = FxHashMap::default();
let result = transform
.apply(StatValue::from_f64(10.0), &deps, &context)
.unwrap();
assert_eq!(result.to_f64(), 10.0);
}
}