clineup 0.2.5

A command-line utility for organizing media files
Documentation
use log::{error, info};
use serde::{Deserialize, Serialize};

#[cfg(target_family = "unix")]
use std::os::unix::fs::symlink;
#[cfg(target_family = "windows")]
use std::os::windows::fs::symlink_file;

use std::path::Path;

#[derive(Debug, Deserialize, Serialize, Clone)]
pub enum OrganizationMode {
    Symlinks,
    Move,
    Copy,
}

pub trait OrganizationStrategy {
    fn organize(&self, _original_file: &Path, _destination: &Path) {}
}

pub struct CopyStrategy {}
impl CopyStrategy {
    pub fn new() -> CopyStrategy {
        CopyStrategy {}
    }
}
impl Default for CopyStrategy {
    fn default() -> Self {
        Self::new()
    }
}
impl OrganizationStrategy for CopyStrategy {
    fn organize(&self, original_file: &Path, destination: &Path) {
        info!(
            "Copying {} to {}",
            original_file.display(),
            destination.display()
        );

        if let Some(parent) = destination.parent() {
            let _ = std::fs::create_dir_all(parent);
        };

        if destination.exists() {
            error!("Destination file already exists. Aborting copy.");
            return;
        }

        let copy_result = std::fs::copy(original_file, destination);

        match copy_result {
            Ok(_) => info!("File copied successfully"),
            Err(e) => error!("Error copying file: {}", e),
        }
    }
}
pub struct SymlinksStrategy {}
impl SymlinksStrategy {
    pub fn new() -> SymlinksStrategy {
        SymlinksStrategy {}
    }
}
impl Default for SymlinksStrategy {
    fn default() -> Self {
        Self::new()
    }
}
#[cfg(target_family = "unix")]
fn make_symlink(original_file: &Path, destination: &Path) {
    let symlink_result = symlink(original_file, destination);
    match symlink_result {
        Ok(_) => info!("File symlinked successfully"),
        Err(e) => error!("Error symlinking file: {}", e),
    }
}
#[cfg(target_family = "windows")]
fn make_symlink(original_file: &Path, destination: &Path) {
    let symlink_result = symlink_file(original_file, destination);
    match symlink_result {
        Ok(_) => info!("File symlinked successfully"),
        Err(e) => error!("Error symlinking file: {}", e),
    }
}
impl OrganizationStrategy for SymlinksStrategy {
    fn organize(&self, original_file: &Path, destination: &Path) {
        info!(
            "Symlinking {} to {}",
            destination.display(),
            original_file.display(),
        );
        if let Some(parent) = destination.parent() {
            let _ = std::fs::create_dir_all(parent);
        };

        if destination.exists() {
            error!("Destination file already exists. Aborting copy.");
            return;
        }

        make_symlink(original_file, destination);
    }
}
pub struct MoveStrategy {}

impl MoveStrategy {
    pub fn new() -> MoveStrategy {
        MoveStrategy {}
    }
}
impl Default for MoveStrategy {
    fn default() -> Self {
        Self::new()
    }
}
impl OrganizationStrategy for MoveStrategy {
    fn organize(&self, original_file: &Path, destination: &Path) {
        info!(
            "Moving {} to {}",
            original_file.display(),
            destination.display(),
        );
        if let Some(parent) = destination.parent() {
            let _ = std::fs::create_dir_all(parent);
        };

        if destination.exists() {
            error!("Destination file already exists. Aborting copy.");
            return;
        }
        let move_result = std::fs::rename(original_file, destination);
        match move_result {
            Ok(_) => info!("File moved successfully"),
            Err(e) => error!("Error moving file: {}", e),
        }
    }
}