llm_coding_tools_core/path/
absolute.rs1use super::PathResolver;
4use crate::error::{ToolError, ToolResult};
5use std::path::PathBuf;
6
7#[derive(Debug, Clone, Copy, Default)]
25pub struct AbsolutePathResolver;
26
27impl PathResolver for AbsolutePathResolver {
28 fn resolve(&self, path: &str) -> ToolResult<PathBuf> {
29 let path = PathBuf::from(path);
30 if !path.is_absolute() {
31 return Err(ToolError::InvalidPath(format!(
32 "path must be absolute: {}",
33 path.display()
34 )));
35 }
36 Ok(path)
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn accepts_absolute_path() {
46 let resolver = AbsolutePathResolver;
47 #[cfg(windows)]
48 let path = "C:\\Users\\user\\file.txt";
49 #[cfg(not(windows))]
50 let path = "/home/user/file.txt";
51
52 let result = resolver.resolve(path);
53 assert!(result.is_ok());
54 assert_eq!(result.unwrap(), PathBuf::from(path));
55 }
56
57 #[test]
58 fn rejects_relative_path() {
59 let resolver = AbsolutePathResolver;
60 let result = resolver.resolve("relative/path.txt");
61 assert!(result.is_err());
62 let err = result.unwrap_err();
63 assert!(matches!(err, ToolError::InvalidPath(_)));
64 assert!(err.to_string().contains("must be absolute"));
65 }
66
67 #[test]
68 fn rejects_dot_relative_path() {
69 let resolver = AbsolutePathResolver;
70 assert!(resolver.resolve("./file.txt").is_err());
71 assert!(resolver.resolve("../file.txt").is_err());
72 }
73
74 #[cfg(windows)]
75 #[test]
76 fn accepts_windows_absolute_path() {
77 let resolver = AbsolutePathResolver;
78 assert!(resolver.resolve("C:\\Users\\file.txt").is_ok());
79 }
80}