use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use layer_conform_core::pipeline::ExtractedFiles;
use layer_conform_core::rule::Rule;
use layer_conform_io::config::{self, Config};
pub const CONFIG_FILE: &str = ".layer-conform.json";
pub fn load_config() -> Result<Config> {
let path = Path::new(CONFIG_FILE);
config::load(path).with_context(|| format!("loading {CONFIG_FILE}"))
}
pub fn compile_rules(cfg: &Config) -> Result<Vec<Rule>> {
layer_conform_io::compile::compile_rules(cfg).with_context(|| "compiling rules")
}
pub fn extract_workspace(root: &Path, restrict_to: &[PathBuf]) -> Result<ExtractedFiles> {
let files = if restrict_to.is_empty() {
layer_conform_io::walker::walk_source_files(root)
} else {
restrict_to
.iter()
.map(|p| if p.is_absolute() { p.clone() } else { root.join(p) })
.collect()
};
let rs_workspace = layer_conform_rs::workspace::discover_workspace(root)
.with_context(|| "discovering Rust workspace")?;
let mut out: ExtractedFiles = HashMap::with_capacity(files.len());
for path in files {
let rel = match path.strip_prefix(root) {
Ok(r) => r.to_path_buf(),
Err(_) => path.clone(),
};
let key = rel.to_string_lossy().into_owned();
let source = fs::read_to_string(&path)
.with_context(|| format!("reading {}", path.display()))?;
let funcs = match path.extension().and_then(|s| s.to_str()) {
Some("rs") => match &rs_workspace {
Some(ws) => layer_conform_rs::parse_file_with_context(
&source,
&layer_conform_rs::FileContext { workspace: ws, file_path: &path },
),
None => layer_conform_rs::parse_file(&source),
},
_ => layer_conform_ts::parse_file(&source),
};
out.insert(key, funcs);
}
Ok(out)
}
pub fn relativize(root: &Path, path: &Path) -> String {
if path.is_absolute() {
path.strip_prefix(root)
.map_or_else(
|_| path.to_string_lossy().into_owned(),
|p| p.to_string_lossy().into_owned(),
)
} else {
path.to_string_lossy().into_owned()
}
}