fastsync 0.5.1

A fast, safe one-way directory synchronization tool for large local folders.
Documentation
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;

use crate::error::{Result, io_context};
use crate::i18n::tr_path;

/// BLAKE3 摘要的固定长度字节表示。
pub type Blake3Digest = [u8; 32];

/// 以流式方式计算文件 BLAKE3 哈希。
///
/// 该函数不会一次性读取整个文件,适合大文件校验和比较。
pub fn blake3_file(path: &Path) -> Result<Blake3Digest> {
    let file = io_context(
        tr_path("io.open_file_for_hash", path.display()),
        File::open(path),
    )?;
    blake3_reader(path, file)
}

/// 从任意流式 reader 计算 BLAKE3 哈希。
///
/// `path` 只用于错误上下文;调用方仍需保证 reader 对应的内容来源正确。
pub fn blake3_reader(path: &Path, reader: impl Read) -> Result<Blake3Digest> {
    let mut reader = BufReader::with_capacity(1024 * 1024, reader);
    let mut hasher = blake3::Hasher::new();
    let mut buffer = [0_u8; 1024 * 1024];

    loop {
        let read = io_context(
            tr_path("io.read_file_for_hash", path.display()),
            reader.read(&mut buffer),
        )?;
        if read == 0 {
            break;
        }
        hasher.update(&buffer[..read]);
    }

    Ok(*hasher.finalize().as_bytes())
}

/// 比较两个文件的 BLAKE3 摘要是否一致。
pub fn same_blake3(left: &Path, right: &Path) -> Result<bool> {
    Ok(blake3_file(left)? == blake3_file(right)?)
}