Added merge
This commit is contained in:
@@ -1,18 +1,27 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub enum MoveOutcome {
|
||||
/// File was moved/renamed to destination.
|
||||
Moved(PathBuf),
|
||||
/// Destination already existed; inbox duplicate was removed.
|
||||
Merged(PathBuf),
|
||||
}
|
||||
|
||||
/// Move a file from inbox to the permanent storage directory.
|
||||
///
|
||||
/// Creates the directory structure: `storage_dir/artist/album/filename`
|
||||
/// Returns the full path of the moved file.
|
||||
///
|
||||
/// If `rename` fails (cross-device), falls back to copy + remove.
|
||||
/// If the destination already exists the inbox copy is removed and
|
||||
/// `MoveOutcome::Merged` is returned instead of an error.
|
||||
pub async fn move_to_storage(
|
||||
storage_dir: &Path,
|
||||
artist: &str,
|
||||
album: &str,
|
||||
filename: &str,
|
||||
source: &Path,
|
||||
) -> anyhow::Result<PathBuf> {
|
||||
) -> anyhow::Result<MoveOutcome> {
|
||||
let artist_dir = sanitize_dir_name(artist);
|
||||
let album_dir = sanitize_dir_name(album);
|
||||
|
||||
@@ -21,9 +30,13 @@ pub async fn move_to_storage(
|
||||
|
||||
let dest = dest_dir.join(filename);
|
||||
|
||||
// Avoid overwriting existing files
|
||||
// File already at destination — remove the inbox duplicate
|
||||
if dest.exists() {
|
||||
anyhow::bail!("Destination already exists: {:?}", dest);
|
||||
if source.exists() {
|
||||
tokio::fs::remove_file(source).await?;
|
||||
tracing::info!(from = ?source, to = ?dest, "merged duplicate into existing storage file");
|
||||
}
|
||||
return Ok(MoveOutcome::Merged(dest));
|
||||
}
|
||||
|
||||
// Try atomic rename first (same filesystem)
|
||||
@@ -37,7 +50,7 @@ pub async fn move_to_storage(
|
||||
}
|
||||
|
||||
tracing::info!(from = ?source, to = ?dest, "moved file to storage");
|
||||
Ok(dest)
|
||||
Ok(MoveOutcome::Moved(dest))
|
||||
}
|
||||
|
||||
/// Remove characters that are unsafe for directory names.
|
||||
|
||||
Reference in New Issue
Block a user