Simple tool for automatic file management
at master 2.6 kB view raw
1// SPDX-FileCopyrightText: 2024 Łukasz Niemier <#@hauleth.dev> 2// 3// SPDX-License-Identifier: EUPL-1.2 4 5use tokio::fs; 6use tokio::process::Command; 7 8use std::path::{Path, PathBuf}; 9 10/// Actions available for file 11#[derive(Clone, Debug, serde::Deserialize)] 12#[serde(rename_all = "snake_case")] 13pub enum Action { 14 /// Run given script with 1st argument. It will be ran in parent directory for given file 15 Script(Box<Path>), 16 /// Move given file to new destination 17 Move(Box<Path>), 18 /// Copy given file to new destination 19 Copy(Box<Path>), 20 /// Print message and do nothing 21 Echo(String), 22 /// Move to trash 23 Trash, 24} 25 26impl Action { 27 pub async fn run(self, source: PathBuf, execute: bool) { 28 self.dry_run(&source).await; 29 30 if execute { 31 self.execute(source).await 32 } 33 } 34 35 pub async fn dry_run(&self, source: &Path) { 36 match self { 37 Action::Script(ref script) => println!("Execute {script:?} {source:?}"), 38 Action::Move(ref dest) => println!("Move {source:?} -> {dest:?}"), 39 Action::Copy(ref dest) => println!("Copy {source:?} -> {dest:?}"), 40 Action::Echo(ref message) => println!("{source:?} - {message}"), 41 Action::Trash => println!("Move {source:?} to trash"), 42 } 43 } 44 45 pub async fn execute(self, source: PathBuf) { 46 match self { 47 Action::Script(ref script) => { 48 Command::new(script.as_ref()) 49 .arg(&source) 50 .current_dir(source.parent().unwrap()) 51 .spawn() 52 .expect("Couldnt spawn process") 53 .wait() 54 .await 55 .expect("Child exited abnormally"); 56 } 57 58 Action::Copy(ref dest_dir) => { 59 let dest = crate::job::normalise_path(dest_dir).join(source.file_name().unwrap()); 60 fs::copy(&source, dest).await.expect("Couldnt copy file"); 61 } 62 63 Action::Move(ref dest_dir) => { 64 let dest = crate::job::normalise_path(dest_dir).join(source.file_name().unwrap()); 65 if let Err(err) = fs::rename(&source, &dest).await { 66 if err.raw_os_error() == Some(libc::EXDEV) { 67 panic!("X dev"); 68 } else { 69 panic!("Cannot move {source:?} -> {dest:?}: {err:?}"); 70 } 71 } 72 } 73 74 Action::Echo(ref message) => println!("{source:?} - {message}"), 75 76 Action::Trash => trash::delete(source).unwrap(), 77 } 78 } 79}