use crate::effects::AnalysisEffect;
use std::path::PathBuf;
use stillwater::effect::prelude::*;
use super::directory::walk_dir_with_config_effect;
use super::file::{file_exists_effect, read_file_effect};
pub fn read_file_if_exists_effect(path: PathBuf) -> AnalysisEffect<Option<String>> {
let path_clone = path.clone();
file_exists_effect(path.clone())
.and_then(move |exists| {
if exists {
read_file_effect(path_clone).map(Some).boxed()
} else {
pure(None).boxed()
}
})
.boxed()
}
pub fn read_files_effect(paths: Vec<PathBuf>) -> AnalysisEffect<Vec<String>> {
let mut effects: Vec<AnalysisEffect<String>> =
paths.into_iter().map(read_file_effect).collect();
if effects.is_empty() {
return pure(Vec::new()).boxed();
}
let first = effects.remove(0);
effects
.into_iter()
.fold(first.map(|s| vec![s]).boxed(), |acc, eff| {
acc.and_then(move |mut results| {
eff.map(move |s| {
results.push(s);
results
})
.boxed()
})
.boxed()
})
}
pub fn walk_and_analyze_effect(
path: PathBuf,
languages: Vec<crate::core::Language>,
) -> AnalysisEffect<Vec<crate::analyzers::batch::FileAnalysisResult>> {
walk_dir_with_config_effect(path, languages)
.and_then(crate::analyzers::batch::analyze_files_effect)
.boxed()
}
pub fn walk_and_validate_effect(
path: PathBuf,
languages: Vec<crate::core::Language>,
) -> AnalysisEffect<crate::effects::AnalysisValidation<Vec<crate::analyzers::batch::ValidatedFile>>>
{
walk_dir_with_config_effect(path, languages)
.map(|files| crate::analyzers::batch::validate_files(&files))
.boxed()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::DebtmapConfig;
use crate::effects::run_effect;
use tempfile::TempDir;
fn create_test_env() -> (TempDir, DebtmapConfig) {
let temp_dir = TempDir::new().unwrap();
(temp_dir, DebtmapConfig::default())
}
#[test]
fn test_read_file_if_exists_effect() {
let (temp_dir, config) = create_test_env();
let file_path = temp_dir.path().join("optional.txt");
std::fs::write(&file_path, "content").unwrap();
let effect = read_file_if_exists_effect(file_path);
let result = run_effect(effect, config.clone());
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some("content".to_string()));
let effect = read_file_if_exists_effect(temp_dir.path().join("missing.txt"));
let result = run_effect(effect, config);
assert!(result.is_ok());
assert!(result.unwrap().is_none());
}
#[test]
fn test_read_files_effect() {
let (temp_dir, config) = create_test_env();
std::fs::write(temp_dir.path().join("a.txt"), "A").unwrap();
std::fs::write(temp_dir.path().join("b.txt"), "B").unwrap();
let paths = vec![temp_dir.path().join("a.txt"), temp_dir.path().join("b.txt")];
let effect = read_files_effect(paths);
let result = run_effect(effect, config);
assert!(result.is_ok());
assert_eq!(result.unwrap(), vec!["A".to_string(), "B".to_string()]);
}
#[test]
fn test_read_files_effect_empty() {
let config = DebtmapConfig::default();
let effect = read_files_effect(vec![]);
let result = run_effect(effect, config);
assert!(result.is_ok());
assert!(result.unwrap().is_empty());
}
}