1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
use crate::input::Delimiter; use crate::output::write_error; use crate::run::{Io, Options, Result, EXIT_CODE_IO_ERROR, EXIT_CODE_OK}; use crate::transfer::fs::{transfer_path, TransferMode}; use crate::transfer::input::PathDiff; use crate::transfer::output::TransferLog; pub trait TransferOptions { fn read_nul(&self) -> bool; fn verbose(&self) -> bool; fn fail_at_end(&self) -> bool; } pub fn run_transfer<O>(options: &O, io: &Io, mode: TransferMode) -> Result where O: Options + TransferOptions, { let delimiter = if options.read_nul() { Delimiter::Byte(0) } else { Delimiter::Newline }; let mut path_diff = PathDiff::new(io.stdin(), delimiter); let mut log = TransferLog::new(io.stdout()); let mut exit_code = EXIT_CODE_OK; while let Some((src_path, dst_path)) = path_diff.read()? { if options.verbose() { log.begin_transfer(mode, &src_path, &dst_path)?; } match transfer_path(&src_path, &dst_path, mode) { Ok(()) => { if options.verbose() { log.end_with_success()?; } } Err(error) => { if options.verbose() { log.end_with_failure()?; } write_error(&mut io.stderr(), &error)?; if options.fail_at_end() { exit_code = EXIT_CODE_IO_ERROR; } else { return Ok(EXIT_CODE_IO_ERROR); } } } } Ok(exit_code) }