use crate::effects::AnalysisEffect;
use crate::env::{AnalysisEnv, RealEnv};
use crate::errors::AnalysisError;
use stillwater::effect::prelude::*;
pub fn cache_get_effect<T>(key: String) -> AnalysisEffect<Option<T>>
where
T: serde::de::DeserializeOwned + Send + 'static,
{
from_fn(move |env: &RealEnv| {
match env.cache().get(&key) {
Some(bytes) => {
match postcard::from_bytes(&bytes) {
Ok(value) => Ok(Some(value)),
Err(e) => {
eprintln!(
"Warning: Failed to deserialize cache value for key '{}': {}",
key, e
);
Ok(None)
}
}
}
None => Ok(None),
}
})
.boxed()
}
pub fn cache_set_effect<T>(key: String, value: T) -> AnalysisEffect<()>
where
T: serde::Serialize + Send + 'static,
{
from_fn(move |env: &RealEnv| {
let bytes = postcard::to_allocvec(&value).map_err(|e| {
AnalysisError::other(format!(
"Failed to serialize cache value for '{}': {}",
key, e
))
})?;
env.cache().set(&key, &bytes).map_err(|e| {
AnalysisError::other(format!("Cache write failed for '{}': {}", key, e.message()))
})
})
.boxed()
}
pub fn cache_invalidate_effect(key: String) -> AnalysisEffect<()> {
from_fn(move |env: &RealEnv| {
env.cache().invalidate(&key).map_err(|e| {
AnalysisError::other(format!(
"Cache invalidation failed for '{}': {}",
key,
e.message()
))
})
})
.boxed()
}
pub fn cache_clear_effect() -> AnalysisEffect<()> {
from_fn(|env: &RealEnv| {
env.cache()
.clear()
.map_err(|e| AnalysisError::other(format!("Cache clear failed: {}", e.message())))
})
.boxed()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::effects::run_effect_with_env;
use crate::env::RealEnv;
#[test]
fn test_cache_operations() {
let env = RealEnv::default();
let set_effect = cache_set_effect("test_key".into(), vec![1, 2, 3]);
assert!(run_effect_with_env(set_effect, &env).is_ok());
let get_effect = cache_get_effect::<Vec<i32>>("test_key".into());
let result = run_effect_with_env(get_effect, &env);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(vec![1, 2, 3]));
let get_effect = cache_get_effect::<Vec<i32>>("nonexistent".into());
let result = run_effect_with_env(get_effect, &env);
assert!(result.is_ok());
assert!(result.unwrap().is_none());
let inv_effect = cache_invalidate_effect("test_key".into());
assert!(run_effect_with_env(inv_effect, &env).is_ok());
let get_effect = cache_get_effect::<Vec<i32>>("test_key".into());
assert!(run_effect_with_env(get_effect, &env).unwrap().is_none());
}
}