fix(tui): apply username folders everywhere and resume in place

Move the sanitizer next to the directory helpers so the CLI download
command and the daemon honour use_username_dirs too, not only the TUI.
Resumed downloads keep the folder they were saved with instead of
nesting the username a second time, and toggling the setting applies
to the next download without a restart. Document the config key.
This commit is contained in:
Michel de Graaf
2026-10-22 14:19:18 +02:00
parent 9805b807e5
commit ea884535a8
14 changed files with 130 additions and 69 deletions
-35
View File
@@ -72,41 +72,6 @@ pub const fn get_spinner_char(state: usize) -> &'static str {
SPINNER_CHARS[state % SPINNER_CHARS.len()]
}
#[must_use]
pub fn sanitize_path_component(name: &str) -> String {
let mut out = name
.chars()
.map(|c| match c {
'/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' => '_',
c if c.is_control() => '_',
c => c,
})
.collect::<String>();
if out.is_empty() || out.ends_with(['.', ' ']) {
out.push('_');
}
if is_reserved(out.as_str()) {
out.insert(0, '_');
}
out
}
#[cfg(target_os = "windows")]
fn is_reserved(name: &str) -> bool {
let stem = name.split('.').next().unwrap_or(name).to_ascii_uppercase();
if matches!(stem.as_str(), "CON" | "PRN" | "AUX" | "NUL") {
true
} else {
matches!(stem.get(..3), Some("COM" | "LPT"))
&& matches!(stem.as_bytes().get(3..), Some([b'1'..=b'9']))
}
}
#[cfg(not(target_os = "windows"))]
fn is_reserved(name: &str) -> bool {
false
}
#[cfg(test)]
mod tests {
use super::*;