Skip to main content

mcp_utils/client/
roots.rs

1use rmcp::model::Root;
2use std::path::Path;
3#[cfg(test)]
4use std::path::PathBuf;
5
6/// Convert a `PathBuf` to a file:// URI string.
7///
8/// This function handles platform-specific path formats:
9/// - Unix: /home/user/project -> <file:///home/user/project>
10/// - Windows: C:\Users\user\project -> <file:///C:/Users/user/project>
11pub fn path_to_file_uri(path: &Path) -> String {
12    #[cfg(unix)]
13    {
14        format!("file://{}", path.display())
15    }
16
17    #[cfg(windows)]
18    {
19        // Convert Windows paths to URI format
20        let path_str = path.display().to_string().replace('\\', "/");
21        format!("file:///{}", path_str)
22    }
23
24    #[cfg(not(any(unix, windows)))]
25    {
26        // Fallback for other platforms
27        format!("file://{}", path.display())
28    }
29}
30
31/// Create a Root from a `PathBuf`.
32///
33/// The path is converted to an absolute file:// URI.
34pub fn root_from_path(path: &Path, name: Option<String>) -> Root {
35    let uri = path_to_file_uri(path);
36    let root = Root::new(uri);
37    match name {
38        Some(n) => root.with_name(n),
39        None => root,
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn test_path_to_file_uri() {
49        let path = PathBuf::from("/home/user/project");
50        let uri = path_to_file_uri(&path);
51        assert_eq!(uri, "file:///home/user/project");
52    }
53
54    #[test]
55    fn test_root_from_path() {
56        let path = PathBuf::from("/home/user/project");
57        let root = root_from_path(&path, Some("Test Project".to_string()));
58
59        assert_eq!(root.uri.as_str(), "file:///home/user/project");
60        assert_eq!(root.name, Some("Test Project".to_string()));
61    }
62
63    #[test]
64    fn test_root_from_path_no_name() {
65        let path = PathBuf::from("/tmp/test");
66        let root = root_from_path(&path, None);
67
68        assert_eq!(root.uri.as_str(), "file:///tmp/test");
69        assert_eq!(root.name, None);
70    }
71
72    #[test]
73    fn test_path_with_spaces() {
74        let path = PathBuf::from("/home/user/my project");
75        let root = root_from_path(&path, None);
76
77        // The URI should preserve spaces (not percent-encoded in this simple implementation)
78        assert_eq!(root.uri.as_str(), "file:///home/user/my project");
79    }
80}