use super::error::LspError;
use crate::config::Config;
use std::path::{Path, PathBuf};
use tower_lsp::lsp_types::Url;
pub fn find_workspace_config(file_uri: &Url) -> Option<PathBuf> {
let file_path = file_uri.to_file_path().ok()?;
let mut dir: &Path = if file_path.is_dir() {
file_path.as_path()
} else {
file_path.parent()?
};
loop {
let candidate = dir.join(".splitrs.toml");
if candidate.exists() {
return Some(candidate);
}
dir = dir.parent()?;
}
}
pub fn reload_config(path: &Path) -> Result<Config, LspError> {
Config::from_file(path).map_err(LspError::from)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
#[test]
fn finds_config_walking_up() {
let temp = std::env::temp_dir().join("splitrs_test_config_walk");
let subdir = temp.join("src").join("deeply").join("nested");
fs::create_dir_all(&subdir).unwrap();
let config_path = temp.join(".splitrs.toml");
fs::write(&config_path, "[splitrs]\nmax_lines = 1000\n").unwrap();
let test_file = subdir.join("foo.rs");
fs::write(&test_file, "").unwrap();
let uri = Url::from_file_path(&test_file).unwrap();
let found = find_workspace_config(&uri);
assert_eq!(found, Some(config_path));
fs::remove_dir_all(&temp).ok();
}
#[test]
fn returns_none_when_no_config() {
let temp = std::env::temp_dir().join("splitrs_test_no_config");
let nested = temp.join("a").join("b").join("c");
fs::create_dir_all(&nested).unwrap();
let test_file = nested.join("bar.rs");
fs::write(&test_file, "").unwrap();
let uri = Url::from_file_path(&test_file).unwrap();
let _ = find_workspace_config(&uri);
fs::remove_dir_all(&temp).ok();
}
#[test]
fn reload_config_reads_file() {
let temp = std::env::temp_dir().join("splitrs_test_reload_config");
fs::create_dir_all(&temp).unwrap();
let config_path = temp.join(".splitrs.toml");
fs::write(&config_path, "[splitrs]\nmax_lines = 500\n").unwrap();
let result = reload_config(&config_path);
assert!(result.is_ok(), "reload_config failed: {:?}", result.err());
fs::remove_dir_all(&temp).ok();
}
}