Skip to content

Commit b43ea38

Browse files
authored
fix: interpret path separators per-platform in extract_title_from_path (#585)
extract_title_from_path only ever receives native local paths: the desktop app and pb CLI pass the opened file's path, and Android copies content URIs to a local cache file before handing the path to the core. Treating a backslash as a separator on unix was therefore speculative generality — and actively wrong, since a backslash is a legal filename character there (a file named "dir\\" got "Untitled" instead of its name). Gate the trailing-backslash check to Windows and split the tests into platform-independent, Windows-only, and unix-only groups. This fixes extracts_title_from_path::case_03, which asserted the Windows answer for a C:\\ path on every platform and failed on macOS.
1 parent 5965ce5 commit b43ea38

1 file changed

Lines changed: 21 additions & 3 deletions

File tree

  • crates/paperback-core/src/parser/util

crates/paperback-core/src/parser/util/path.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use std::path::Path;
22

3+
/// Derives a fallback document title from the path of the file being opened.
4+
/// Inputs are always native local paths, so separators are interpreted
5+
/// per-platform: on unix, a backslash is an ordinary filename character.
36
#[must_use]
47
pub fn extract_title_from_path(path: &str) -> String {
58
let trimmed = path.trim();
69
if trimmed.is_empty() {
710
return "Untitled".to_string();
811
}
9-
if trimmed.ends_with('/') || trimmed.ends_with('\\') {
12+
if trimmed.ends_with('/') || (cfg!(windows) && trimmed.ends_with('\\')) {
1013
return "Untitled".to_string();
1114
}
1215
Path::new(trimmed).file_stem().and_then(|s| s.to_str()).unwrap_or("Untitled").to_string()
@@ -21,9 +24,7 @@ mod tests {
2124
#[rstest]
2225
#[case("foo.txt", "foo")]
2326
#[case("/home/quin/books/worm.epub", "worm")]
24-
#[case("C:\\Users\\Quin\\Desktop\\file.log", "file")]
2527
#[case("/path/with/trailing/slash/", "Untitled")]
26-
#[case("C:\\path\\with\\trailing\\slash\\", "Untitled")]
2728
#[case(" spaced.txt ", "spaced")]
2829
#[case("", "Untitled")]
2930
#[case("README", "README")]
@@ -34,4 +35,21 @@ mod tests {
3435
fn extracts_title_from_path(#[case] input: &str, #[case] expected: &str) {
3536
assert_eq!(extract_title_from_path(input), expected);
3637
}
38+
39+
#[cfg(windows)]
40+
#[rstest]
41+
#[case("C:\\Users\\Quin\\Desktop\\file.log", "file")]
42+
#[case("C:\\path\\with\\trailing\\slash\\", "Untitled")]
43+
fn extracts_title_from_windows_path(#[case] input: &str, #[case] expected: &str) {
44+
assert_eq!(extract_title_from_path(input), expected);
45+
}
46+
47+
/// On unix, a backslash is an ordinary filename character, not a separator.
48+
#[cfg(not(windows))]
49+
#[rstest]
50+
#[case("weird\\name.txt", "weird\\name")]
51+
#[case("trailing\\", "trailing\\")]
52+
fn backslash_is_a_filename_character_on_unix(#[case] input: &str, #[case] expected: &str) {
53+
assert_eq!(extract_title_from_path(input), expected);
54+
}
3755
}

0 commit comments

Comments
 (0)