llm_coding_tools_core/path/
absolute.rs

1//! Absolute path resolver implementation.
2
3use super::PathResolver;
4use crate::error::{ToolError, ToolResult};
5use std::path::PathBuf;
6
7/// Path resolver that requires absolute paths.
8///
9/// This is the simplest resolver - it validates that paths are absolute
10/// and returns them as-is. No directory restrictions are applied.
11///
12/// # Example
13///
14/// ```
15/// use llm_coding_tools_core::path::{PathResolver, AbsolutePathResolver};
16///
17/// let resolver = AbsolutePathResolver;
18/// #[cfg(windows)]
19/// assert!(resolver.resolve("C:\\Users\\user\\file.txt").is_ok());
20/// #[cfg(not(windows))]
21/// assert!(resolver.resolve("/home/user/file.txt").is_ok());
22/// assert!(resolver.resolve("relative/path.txt").is_err());
23/// ```
24#[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}