use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct ResolveResult {
pub path: PathBuf,
pub exact: bool,
pub suggestions: Vec<PathBuf>,
}
pub fn resolve_path(path: &str, use_parent: bool, force: bool) -> ResolveResult {
let p = PathBuf::from(path);
if force {
return ResolveResult {
path: p,
exact: true,
suggestions: vec![],
};
}
if p.exists() {
return ResolveResult {
path: p,
exact: true,
suggestions: vec![],
};
}
if use_parent {
if let Some(parent) = find_existing_parent(&p) {
let suggestions = list_suggestions(&parent);
return ResolveResult {
path: parent,
exact: false,
suggestions,
};
}
}
if let Some(parent) = p.parent() {
if parent.exists() {
let suggestions = list_suggestions(parent);
return ResolveResult {
path: p,
exact: false,
suggestions,
};
}
}
ResolveResult {
path: p,
exact: false,
suggestions: vec![],
}
}
fn find_existing_parent(path: &Path) -> Option<PathBuf> {
let mut current = path;
loop {
if current.exists() {
return Some(current.to_path_buf());
}
match current.parent() {
Some(parent) => current = parent,
None => return None,
}
}
}
fn list_suggestions(dir: &Path) -> Vec<PathBuf> {
let mut suggestions = Vec::new();
if let Ok(entries) = std::fs::read_dir(dir) {
for entry in entries.flatten() {
if entry.path().is_dir() {
suggestions.push(entry.path());
}
}
}
suggestions.sort();
suggestions.truncate(10);
suggestions
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_resolve_existing_path() {
let tmp = std::env::temp_dir();
let result = resolve_path(tmp.to_str().unwrap(), false, false);
assert!(result.exact);
}
#[test]
fn test_resolve_nonexistent_force() {
let result = resolve_path("/nonexistent/path/12345", false, true);
assert!(result.exact); }
#[test]
fn test_resolve_nonexistent_with_parent() {
let tmp = std::env::temp_dir();
let fake = tmp.join("wincd_test_nonexistent_12345");
let result = resolve_path(fake.to_str().unwrap(), true, false);
assert!(!result.exact);
assert!(result.path.exists());
}
#[test]
fn test_list_suggestions() {
let tmp = std::env::temp_dir();
let suggestions = list_suggestions(&tmp);
assert!(!suggestions.is_empty());
}
}