use std::env;
use std::path::PathBuf;
use crate::error::Result;
pub struct ConfigDiscovery;
impl ConfigDiscovery {
pub fn find() -> Result<Option<PathBuf>> {
Self::find_from(env::current_dir()?)
}
pub fn find_from(start: PathBuf) -> Result<Option<PathBuf>> {
let mut current = start;
loop {
let config_path = current.join("xcargo.toml");
if config_path.exists() && config_path.is_file() {
return Ok(Some(config_path));
}
match current.parent() {
Some(parent) => current = parent.to_path_buf(),
None => break, }
}
Ok(None)
}
pub fn exists_in_current() -> Result<bool> {
let current = env::current_dir()?;
Ok(current.join("xcargo.toml").exists())
}
pub fn default_path() -> Result<PathBuf> {
Ok(env::current_dir()?.join("xcargo.toml"))
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_find_in_current_dir() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("xcargo.toml");
fs::write(&config_path, "[targets]\n").unwrap();
let found = ConfigDiscovery::find_from(temp.path().to_path_buf())
.unwrap();
assert!(found.is_some());
assert_eq!(found.unwrap(), config_path);
}
#[test]
fn test_find_in_parent_dir() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("xcargo.toml");
let sub_dir = temp.path().join("sub");
fs::write(&config_path, "[targets]\n").unwrap();
fs::create_dir(&sub_dir).unwrap();
let found = ConfigDiscovery::find_from(sub_dir).unwrap();
assert!(found.is_some());
assert_eq!(found.unwrap(), config_path);
}
#[test]
fn test_not_found() {
let temp = TempDir::new().unwrap();
let found = ConfigDiscovery::find_from(temp.path().to_path_buf())
.unwrap();
assert!(found.is_none());
}
#[test]
fn test_default_path() {
let path = ConfigDiscovery::default_path().unwrap();
assert!(path.ends_with("xcargo.toml"));
}
}