#![allow(
clippy::collapsible_match,
clippy::io_other_error,
clippy::disallowed_methods,
clippy::unnecessary_debug_formatting
)]
use std::io::{Error, ErrorKind};
use std::path::{Path, PathBuf};
use std::{env, fs};
pub fn resolve_project_file(dir: &Path) -> Result<Option<PathBuf>, Error> {
let mut current = if dir.is_relative() {
env::current_dir()?.join(dir)
} else {
dir.to_path_buf()
};
current = fs::canonicalize(current)?;
loop {
match get_toml_path(¤t) {
Ok(Some(path)) => return Ok(Some(path)),
Err(e) => return Err(e),
_ => (),
}
if !current.pop() {
break;
}
}
Ok(None)
}
fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
const CONFIG_FILE_NAMES: [&str; 2] = [".rustfmt.toml", "rustfmt.toml"];
for config_file_name in &CONFIG_FILE_NAMES {
let config_file = dir.join(config_file_name);
match fs::metadata(&config_file) {
Ok(ref md) if md.is_file() => return Ok(Some(config_file.canonicalize()?)),
Err(e) => {
if e.kind() != ErrorKind::NotFound {
let ctx = format!("Failed to get metadata for config file {config_file:?}");
let err = anyhow::Error::new(e).context(ctx);
return Err(Error::new(ErrorKind::Other, err));
}
}
_ => {}
}
}
Ok(None)
}