mirror of
https://github.com/veeso/termscp.git
synced 2026-08-30 17:05:54 -07:00
fix(transfer): enqueue full destination path instead of directory
Queued transfers stored only the destination directory as the target path. Downstream upload logic treats the queued destination as the full file path and passes it straight to create_file, so transfers failed with a Failure error when the remote target resolved to a directory. Append each entry's file name to the destination directory at enqueue time in both enqueue_file and enqueue_all, matching the single-file transfer path which already builds the full target path.
This commit is contained in:
+31
-2
@@ -159,11 +159,18 @@ impl FileExplorer {
|
||||
.insert(PathBuf::from(src), PathBuf::from(dst));
|
||||
}
|
||||
|
||||
/// Enqueue all files for transfer
|
||||
/// Enqueue all files for transfer.
|
||||
///
|
||||
/// `dst` is the destination *directory*; each entry is enqueued with its own
|
||||
/// file name appended, so the stored destination is the full target path.
|
||||
pub fn enqueue_all(&mut self, dst: &Path) {
|
||||
let files: Vec<_> = self.iter_files().map(|f| f.path.clone()).collect();
|
||||
for file in files {
|
||||
self.enqueue(&file, dst);
|
||||
let dest = match file.file_name() {
|
||||
Some(name) => dst.join(name),
|
||||
None => dst.to_path_buf(),
|
||||
};
|
||||
self.enqueue(&file, &dest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,6 +666,28 @@ mod tests {
|
||||
assert_eq!(explorer.enqueued().len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_should_enqueue_all_with_dest_file_name() {
|
||||
let mut explorer: FileExplorer = FileExplorer::default();
|
||||
explorer.set_files(vec![
|
||||
make_fs_entry("a.txt", false),
|
||||
make_fs_entry("b.txt", false),
|
||||
]);
|
||||
// Enqueue all into a remote destination directory
|
||||
explorer.enqueue_all(Path::new("/remote/dir"));
|
||||
let queue = explorer.enqueued();
|
||||
assert_eq!(queue.len(), 2);
|
||||
// Destination must be the directory joined with the file name, not the directory alone
|
||||
assert_eq!(
|
||||
queue.get(Path::new("a.txt")).unwrap(),
|
||||
Path::new("/remote/dir/a.txt")
|
||||
);
|
||||
assert_eq!(
|
||||
queue.get(Path::new("b.txt")).unwrap(),
|
||||
Path::new("/remote/dir/b.txt")
|
||||
);
|
||||
}
|
||||
|
||||
fn make_fs_entry(name: &str, is_dir: bool) -> File {
|
||||
let t: SystemTime = SystemTime::now();
|
||||
let metadata = Metadata {
|
||||
|
||||
@@ -355,7 +355,12 @@ impl FileTransferActivity {
|
||||
self.browser.explorer_mut().dequeue(&src);
|
||||
} else {
|
||||
debug!("Marking file {}", src.display());
|
||||
let dest = self.browser.other_explorer_no_found().wrkdir.clone();
|
||||
// Destination is the other pane's working directory joined with the file
|
||||
// name, so the queued entry holds the full target path (not just the dir).
|
||||
let mut dest = self.browser.other_explorer_no_found().wrkdir.clone();
|
||||
if let Some(name) = src.file_name() {
|
||||
dest.push(name);
|
||||
}
|
||||
self.browser.explorer_mut().enqueue(&src, &dest);
|
||||
}
|
||||
self.reload_browser_file_list();
|
||||
|
||||
Reference in New Issue
Block a user