diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-10 14:40:37 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-10 14:40:37 +0800 |
| commit | 6b18873666e17ab68ffce799b1707c030166738f (patch) | |
| tree | 8a32b1524a68ce1591bdc897fd37ac456e0932c9 | |
| parent | 471d11e12d1bbbf29a0c07a00311ebe5eac893ec (diff) | |
fix: strip verbatim prefix from canonicalized paths on Windows
Refactor `find_project_root` to use `deverbatim` on canonicalized paths,
removing the `\\?\` prefix on Windows to ensure proper path handling.
| -rw-r--r-- | mingling_cli/src/proj_mgr/cmd_class_add.rs | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/mingling_cli/src/proj_mgr/cmd_class_add.rs b/mingling_cli/src/proj_mgr/cmd_class_add.rs index 5973252..456ec2f 100644 --- a/mingling_cli/src/proj_mgr/cmd_class_add.rs +++ b/mingling_cli/src/proj_mgr/cmd_class_add.rs @@ -54,7 +54,7 @@ pub fn class_add(args: EntryClassAdd) -> Next { /// Walk upward from `start` to find the first directory containing `.mling`. fn find_project_root(start: &Path) -> Option<PathBuf> { - let mut dir = fs::canonicalize(start).ok()?; + let mut dir = deverbatim(&fs::canonicalize(start).ok()?); loop { if dir.join(".mling").is_dir() { return Some(dir); @@ -65,6 +65,28 @@ fn find_project_root(start: &Path) -> Option<PathBuf> { } } +/// Deverbatim a Windows path: strip the `\\?\` prefix that `fs::canonicalize` +/// may add. On non-Windows platforms this is a no-op. +/// +/// On Windows, canonical paths sometimes carry a verbatim prefix like +/// `\\?\C:\...`. This function removes that prefix. For UNC paths such as +/// `\\?\UNC\server\share`, the prefix is converted back to the conventional +/// `\\server\share` form. +fn deverbatim(path: &Path) -> PathBuf { + if !cfg!(windows) { + return path.to_path_buf(); + } + let as_string = path.to_string_lossy(); + if let Some(rest) = as_string.strip_prefix(r"\\?\") { + // Turns `\\?\UNC\server\share` back into `\\server\share`. + if let Some(share) = rest.strip_prefix("UNC\\") { + return PathBuf::from(format!(r"\\{share}")); + } + return PathBuf::from(rest.to_owned()); + } + path.to_path_buf() +} + /// Read `.mling/classes.toml`, find the class template and render it with the /// name-derived parameters into `<output-dir>/<snake_case>.rs`. #[chain(routeify)] |
