Forge
csharp4405de34
1#nullable enable
2
3namespace CascadeIDE.Services.Intercom;
4
5internal static class AttachmentAnchorPaths
6{
7 public static bool TryResolveAbsolute(string file, string? workspaceRoot, out string absolute, out string error)
8 {
9 absolute = "";
10 error = "";
11
12 var trimmed = file.Trim();
13 if (Path.IsPathRooted(trimmed))
14 {
15 if (!CanonicalFilePath.TryNormalize(trimmed, out absolute))
16 {
17 error = "не удалось нормализовать абсолютный путь.";
18 return false;
19 }
20
21 return true;
22 }
23
24 if (string.IsNullOrWhiteSpace(workspaceRoot))
25 {
26 error = "относительный file без загруженного workspace.";
27 return false;
28 }
29
30 var combined = Path.Combine(workspaceRoot.Trim(), trimmed.Replace('/', Path.DirectorySeparatorChar));
31 if (!CanonicalFilePath.TryNormalize(combined, out absolute))
32 {
33 error = "не удалось нормализовать путь относительно workspace.";
34 return false;
35 }
36
37 return true;
38 }
39
40 public static string? ToWorkspaceRelative(string absoluteOrRelative, string? workspaceRoot)
41 {
42 if (string.IsNullOrWhiteSpace(absoluteOrRelative))
43 return null;
44
45 var trimmed = absoluteOrRelative.Trim();
46 if (!Path.IsPathRooted(trimmed))
47 return trimmed.Replace('\\', '/');
48
49 if (string.IsNullOrWhiteSpace(workspaceRoot)
50 || !CanonicalFilePath.TryNormalize(workspaceRoot.Trim(), out var rootNorm)
51 || !CanonicalFilePath.TryNormalize(trimmed, out var fileNorm))
52 {
53 return trimmed.Replace('\\', '/');
54 }
55
56 if (!fileNorm.StartsWith(rootNorm, StringComparison.OrdinalIgnoreCase))
57 return trimmed.Replace('\\', '/');
58
59 var rel = fileNorm.Length == rootNorm.Length
60 ? ""
61 : fileNorm[rootNorm.Length..].TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
62 return rel.Replace('\\', '/');
63 }
64}
65
View only · write via MCP/CIDE