Skip to main content

cc_sync_session/
file_path_converter.rs

1use std::collections::BTreeSet;
2use std::path::PathBuf;
3
4pub fn dir_path_to_claude_code_stype(dir_path: PathBuf) -> anyhow::Result<String> {
5    if !dir_path.is_absolute() {
6        return Err(anyhow::anyhow!("Path must be absolute"));
7    }
8    if dir_path.is_file() {
9        return Err(anyhow::anyhow!("Path must be a directory, not a file"));
10    }
11   
12    // Convert path to string and normalize
13    let path_str = dir_path.to_string_lossy();
14    
15    // Remove leading slash and replace path separators with dashes
16    let without_leading_slash = path_str.trim_start_matches('/');
17    let with_dashes = without_leading_slash.replace('/', "-").replace('.', "-");
18    
19    // Add leading dash
20    Ok(format!("-{}", with_dashes))
21}
22
23pub fn claude_code_stype_to_file_path(code_stype: &str) -> BTreeSet<PathBuf> {
24    let mut results = BTreeSet::new();
25    
26    // Remove leading dash if present
27    let without_leading_dash = code_stype.strip_prefix('-').unwrap_or(code_stype);
28    
29    // Replace dashes with slashes to create base path
30    let base_path = format!("/{}", without_leading_dash.replace('-', "/"));
31    results.insert(PathBuf::from(base_path));
32    
33    // Since dots were converted to dashes, we need to consider possible original paths
34    // For example, "-Users-yuta-github-com" could be:
35    // - /Users/yuta/github.com
36    // - /Users/yuta/github/com
37    // For now, we'll just return the basic conversion
38    // A more sophisticated implementation would need to check common patterns
39    
40    results
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    
47    #[test]
48    fn test_file_path_to_claude_code_stype() {
49        let path = PathBuf::from("/path/to");
50        let result = dir_path_to_claude_code_stype(path);
51        // Add assertions based on expected output
52        assert_eq!(result.unwrap(), "-path-to"); // Replace with actual expected output
53    }
54
55    #[test]
56    fn test_file_path_to_claude_code_stype_with_dot() {
57        let path = PathBuf::from("/path/to/github.com");
58        let result = dir_path_to_claude_code_stype(path);
59        // Add assertions based on expected output
60        assert_eq!(result.unwrap(), "-path-to-github-com"); // Replace with actual expected output
61    }
62
63
64    #[test]
65    fn test_claude_code_stype_to_file_path() {
66        let code_stype = "-path-to";
67        let result = claude_code_stype_to_file_path(code_stype);
68        // Add assertions based on expected output
69        assert!(result.contains(&PathBuf::from("/path/to")));
70    }
71    
72    /// prop-test for file path conversion back to back consistency
73    #[test]
74    fn test_file_path_conversion_consistency() {
75        let original_path = PathBuf::from("/path/to/original");
76        let cc_stype = dir_path_to_claude_code_stype(original_path.clone()).unwrap();
77        let converted_paths = claude_code_stype_to_file_path(&cc_stype);
78        
79        // The original path should be one of the possible results
80        assert!(converted_paths.contains(&original_path));
81    }
82}