win-rar 0.1.0

A Windows archive manager supporting ZIP, 7z, RAR, TAR with encryption, shell integration, and drag-and-drop
// Copyright (c) 北京锋通科技有限公司 — 郭玉峰、吴琼
// SPDX-License-Identifier: MIT

use tauri::Emitter;

use crate::archive::types::*;
use crate::archive::{zip_engine::ZipEngine, rar_engine::RarEngine, sevenz_engine::SevenZEngine, tar_engine::TarEngine};

/// 列出归档内容
#[tauri::command]
pub fn list_archive(path: String) -> Result<ArchiveInfo, String> {
    let format = ArchiveFormat::from_path(&path);

    match format {
        ArchiveFormat::Zip => ZipEngine::list(&path),
        ArchiveFormat::Rar => RarEngine::list(&path),
        ArchiveFormat::SevenZ => SevenZEngine::list(&path),
        ArchiveFormat::Tar | ArchiveFormat::TarGz | ArchiveFormat::TarBz2 | ArchiveFormat::TarXz => {
            TarEngine::list(&path, format)
        }
        _ => Err(format!("不支持的格式: {}", path)),
    }
}

/// 解压归档(异步执行,实时推送进度)
#[tauri::command]
pub async fn extract_archive(
    path: String,
    options: ExtractOptions,
    app: tauri::AppHandle,
) -> Result<TaskResult, String> {
    let format = ArchiveFormat::from_path(&path);

    let result = tokio::task::spawn_blocking(move || {
        let app_clone = app.clone();
        let progress_cb = move |info: ProgressInfo| {
            let _ = app_clone.emit("extract-progress", &info);
        };

        match format {
            ArchiveFormat::Zip => ZipEngine::extract(&path, &options, &progress_cb),
            ArchiveFormat::Rar => RarEngine::extract(&path, &options, &progress_cb),
            ArchiveFormat::SevenZ => SevenZEngine::extract(&path, &options, &progress_cb),
            ArchiveFormat::Tar | ArchiveFormat::TarGz | ArchiveFormat::TarBz2 | ArchiveFormat::TarXz => {
                TarEngine::extract(&path, format, &options, &progress_cb)
            }
            _ => Err(format!("不支持的格式: {}", path)),
        }
    })
    .await
    .map_err(|e| format!("任务执行失败: {}", e))?;

    result
}

/// 压缩文件(异步执行,实时推送进度)
#[tauri::command]
pub async fn compress_files(
    files: Vec<String>,
    options: CompressOptions,
    app: tauri::AppHandle,
) -> Result<TaskResult, String> {
    let result = tokio::task::spawn_blocking(move || {
        let app_clone = app.clone();
        let progress_cb = move |info: ProgressInfo| {
            let _ = app_clone.emit("compress-progress", &info);
        };

        match options.format {
            ArchiveFormat::Zip => ZipEngine::compress(&files, &options, &progress_cb),
            ArchiveFormat::SevenZ => SevenZEngine::compress(&files, &options, &progress_cb),
            ArchiveFormat::Tar | ArchiveFormat::TarGz | ArchiveFormat::TarBz2 | ArchiveFormat::TarXz => {
                TarEngine::compress(&files, &options, &progress_cb)
            }
            ArchiveFormat::Rar => {
                let support = RarEngine::find_winrar();
                match support.winrar_path {
                    Some(winrar_path) => {
                        RarEngine::compress_with_winrar(&files, &options, &winrar_path, &progress_cb)
                    }
                    None => Err("系统未安装 WinRAR,无法创建 RAR 归档。请安装 WinRAR 后重试。".to_string()),
                }
            }
            _ => Err(format!("不支持的压缩格式: {:?}", options.format)),
        }
    })
    .await
    .map_err(|e| format!("任务执行失败: {}", e))?;

    result
}

/// 检测文件格式
#[tauri::command]
pub fn detect_format(path: String) -> Result<ArchiveFormat, String> {
    let format = ArchiveFormat::from_path(&path);
    if format == ArchiveFormat::Unknown {
        Err("无法识别的文件格式".to_string())
    } else {
        Ok(format)
    }
}

/// 检查 RAR 支持状态
#[tauri::command]
pub fn check_rar_support() -> Result<RarSupport, String> {
    Ok(RarEngine::find_winrar())
}