fix(utils): display_path normalizes home-relative suffix to platform separator

`display_path_with_home` joined the `~` prefix with `MAIN_SEPARATOR_STR`
but called `rest.display()` for the suffix, which preserves whatever
separators the input carried. On Windows that produced mixed-separator
output like `~\projects/foo` for any path that came in with forward
slashes — visible in the tests that #506 added to lock down the
contract (the tests passed locally on Unix but failed on the
windows-latest CI runner).

Walk `rest.components()` and join each `Normal` component with
`MAIN_SEPARATOR_STR`. Pure-Rust, no extra deps, behavior is
byte-identical on Unix because the input separator was already `/`.

Verified locally:
- `cargo test -p deepseek-tui --locked display_path` ✓ (5 passed)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hunter Bown
2026-05-03 02:17:50 -05:00
parent ad8064b143
commit dd3882e1bf
+11 -2
View File
@@ -344,6 +344,10 @@ pub fn display_path(path: &Path) -> String {
/// Like [`display_path`] but takes an explicit home directory instead of
/// reading `$HOME` / `dirs::home_dir()`. Used in tests and anywhere the
/// caller already has the home path available.
///
/// The home-relative suffix is rejoined with the platform separator
/// (`\` on Windows, `/` elsewhere) by walking the path's components, so
/// inputs that carried foreign separators don't leak through.
#[must_use]
pub fn display_path_with_home(path: &Path, home: Option<&Path>) -> String {
let Some(home) = home else {
@@ -353,8 +357,13 @@ pub fn display_path_with_home(path: &Path, home: Option<&Path>) -> String {
if rest.as_os_str().is_empty() {
return "~".to_string();
}
let sep = std::path::MAIN_SEPARATOR;
return format!("~{sep}{}", rest.display());
let sep = std::path::MAIN_SEPARATOR_STR;
let mut out = String::from("~");
for component in rest.components() {
out.push_str(sep);
out.push_str(&component.as_os_str().to_string_lossy());
}
return out;
}
path.display().to_string()
}