Can perform basic file copy
This commit is contained in:
		@@ -1,7 +1,8 @@
 | 
			
		||||
use crate::app_config::AppConfig;
 | 
			
		||||
use crate::constants;
 | 
			
		||||
use crate::utils::file_size_utils::FileSize;
 | 
			
		||||
use std::os::linux::fs::MetadataExt;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
use std::time::UNIX_EPOCH;
 | 
			
		||||
 | 
			
		||||
@@ -11,9 +12,11 @@ enum DisksError {
 | 
			
		||||
    Parse(&'static str),
 | 
			
		||||
    #[error("DiskCreateError")]
 | 
			
		||||
    Create,
 | 
			
		||||
    #[error("DiskConvertError: {0}")]
 | 
			
		||||
    Convert(String),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Copy, Clone)]
 | 
			
		||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Copy, Clone, PartialEq, Eq)]
 | 
			
		||||
#[serde(tag = "format")]
 | 
			
		||||
pub enum DiskFileFormat {
 | 
			
		||||
    Raw {
 | 
			
		||||
@@ -42,6 +45,7 @@ impl DiskFileFormat {
 | 
			
		||||
/// Disk file information
 | 
			
		||||
#[derive(serde::Serialize)]
 | 
			
		||||
pub struct DiskFileInfo {
 | 
			
		||||
    pub file_path: PathBuf,
 | 
			
		||||
    pub file_size: FileSize,
 | 
			
		||||
    #[serde(flatten)]
 | 
			
		||||
    pub format: DiskFileFormat,
 | 
			
		||||
@@ -83,6 +87,7 @@ impl DiskFileInfo {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Ok(Self {
 | 
			
		||||
            file_path: file.to_path_buf(),
 | 
			
		||||
            name,
 | 
			
		||||
            file_size: FileSize::from_bytes(metadata.len() as usize),
 | 
			
		||||
            format,
 | 
			
		||||
@@ -145,7 +150,62 @@ impl DiskFileInfo {
 | 
			
		||||
 | 
			
		||||
    /// Copy / convert file disk image into a new destination with optionally a new file format
 | 
			
		||||
    pub fn convert(&self, dest_file: &Path, dest_format: DiskFileFormat) -> anyhow::Result<()> {
 | 
			
		||||
        todo!()
 | 
			
		||||
        // Create a temporary directory to perform the operation
 | 
			
		||||
        let temp_dir = tempfile::tempdir_in(&AppConfig::get().temp_dir)?;
 | 
			
		||||
        let temp_file = temp_dir.path().join("temp_file");
 | 
			
		||||
 | 
			
		||||
        // Prepare the conversion
 | 
			
		||||
        let mut cmd = match (self.format, dest_format) {
 | 
			
		||||
            // Dumb copy of file
 | 
			
		||||
            (a, b) if a == b => {
 | 
			
		||||
                let mut cmd = Command::new(constants::COPY_PROGRAM);
 | 
			
		||||
                cmd.arg("--sparse=auto")
 | 
			
		||||
                    .arg(&self.file_path)
 | 
			
		||||
                    .arg(&temp_file);
 | 
			
		||||
                cmd
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // By default, conversion is unsupported
 | 
			
		||||
            (src, dest) => {
 | 
			
		||||
                return Err(DisksError::Convert(format!(
 | 
			
		||||
                    "Conversion from {src:?} to {dest:?} is not supported!"
 | 
			
		||||
                ))
 | 
			
		||||
                .into());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Execute the conversion
 | 
			
		||||
        let command_s = format!(
 | 
			
		||||
            "{} {}",
 | 
			
		||||
            cmd.get_program().display(),
 | 
			
		||||
            cmd.get_args()
 | 
			
		||||
                .map(|a| format!("'{}'", a.display()))
 | 
			
		||||
                .collect::<Vec<String>>()
 | 
			
		||||
                .join(" ")
 | 
			
		||||
        );
 | 
			
		||||
        let cmd_output = cmd.output()?;
 | 
			
		||||
        if !cmd_output.status.success() {
 | 
			
		||||
            return Err(DisksError::Convert(format!(
 | 
			
		||||
                "Command failed:\n{command_s}\nStatus: {}\nstdout: {}\nstderr: {}",
 | 
			
		||||
                cmd_output.status,
 | 
			
		||||
                String::from_utf8_lossy(&cmd_output.stdout),
 | 
			
		||||
                String::from_utf8_lossy(&cmd_output.stderr)
 | 
			
		||||
            ))
 | 
			
		||||
            .into());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check the file was created
 | 
			
		||||
        if !temp_file.is_file() {
 | 
			
		||||
            return Err(DisksError::Convert(
 | 
			
		||||
                "Temporary was not created after execution of command!".to_string(),
 | 
			
		||||
            )
 | 
			
		||||
            .into());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Move the file to its final location
 | 
			
		||||
        std::fs::rename(temp_file, dest_file)?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user