tldr_cli/
path_validation.rs1use std::path::Path;
20
21use anyhow::{bail, Result};
22
23pub fn require_directory(path: &Path, command: &str) -> Result<()> {
29 if !path.exists() {
30 bail!("Path not found: {}", path.display());
31 }
32 if path.is_file() {
33 bail!(
34 "{} requires a directory; got file '{}'. Pass the project root \
35 or omit the argument to use the current directory.",
36 command,
37 path.display()
38 );
39 }
40 if !path.is_dir() {
41 bail!(
42 "{} requires a directory; got non-directory path '{}'. Pass the \
43 project root or omit the argument to use the current directory.",
44 command,
45 path.display()
46 );
47 }
48 Ok(())
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use std::fs;
55 use tempfile::tempdir;
56
57 #[test]
58 fn directory_passes() {
59 let dir = tempdir().unwrap();
60 require_directory(dir.path(), "hubs").unwrap();
61 }
62
63 #[test]
64 fn file_fails_with_clear_message() {
65 let dir = tempdir().unwrap();
66 let file = dir.path().join("a.py");
67 fs::write(&file, "x = 1\n").unwrap();
68 let err = require_directory(&file, "hubs").unwrap_err().to_string();
69 assert!(err.contains("hubs requires a directory"), "{}", err);
70 assert!(err.contains(file.to_string_lossy().as_ref()), "{}", err);
71 }
72
73 #[test]
74 fn missing_path_fails() {
75 let err = require_directory(Path::new("/no/such/path/xyz"), "hubs")
76 .unwrap_err()
77 .to_string();
78 assert!(err.contains("Path not found"), "{}", err);
79 }
80}