rz-archive 0.15.0

Multi-format archive tool — tar, zip, 7z with a unified CLI
Documentation
use camino::Utf8PathBuf;
use globset::GlobSet;
use serde::Serialize;

use crate::progress::{NoProgress, ProgressReport};

pub mod cmd;
pub mod error;
pub mod filter;
pub mod format;
pub mod modify;
pub mod progress;
pub mod seven_z;
pub mod tar;
pub mod tar_raw;
#[cfg(feature = "bzip2")]
pub mod tar_bz2;
pub mod tar_gz;
pub mod tar_xz;
pub mod tar_zst;
pub mod zip;

/// Metadata for a single entry within an archive.
#[derive(Serialize)]
pub struct Entry {
    pub path: Utf8PathBuf,
    pub size: u64,
    pub mtime: u64,
    pub mode: u32,
    pub is_dir: bool,
    /// Symlink/hardlink target, where the format exposes it without reading
    /// entry data blocks: tar always, zip for unencrypted symlink entries,
    /// 7z never (targets live inside the solid stream).  Lossy-decoded —
    /// used for display and for dry-run's structural traversal check, never
    /// for extraction itself.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub link_target: Option<String>,
}

/// Summary metadata for an archive.
#[derive(Serialize)]
pub struct ArchiveInfo {
    pub format: &'static str,
    pub entry_count: usize,
    pub total_uncompressed: u64,
    pub compressed_size: u64,
}

/// Options for compress operations.
pub struct CompressOpts<'a> {
    pub level: Option<u32>,
    pub excludes: GlobSet,
    pub follow_symlinks: bool,
    pub exclude_vcs_ignores: bool,
    pub no_recursion: bool,
    pub progress: &'a dyn ProgressReport,
    /// Override mtime on all entries (unix timestamp).
    pub fixed_mtime: Option<u64>,
    /// Override uid on all entries.
    pub fixed_uid: Option<u64>,
    /// Override gid on all entries.
    pub fixed_gid: Option<u64>,
    /// Override permission mode on all entries (low 12 bits).
    pub fixed_mode: Option<u32>,
    /// Include only entries with mtime strictly greater than this (unix seconds).
    pub newer_than: Option<i64>,
    /// Include only entries with mtime strictly less than this (unix seconds).
    pub older_than: Option<i64>,
    /// When `true`, top-level inputs that fail to stat are warned about and
    /// skipped instead of aborting the whole archive.  An empty result still
    /// errors out — we never produce an empty archive.
    pub ignore_failed_read: bool,
    /// Password for encrypting the archive (zip and 7z only).
    pub password: Option<String>,
}

/// Options for decompress operations.
pub struct DecompressOpts<'a> {
    pub force: bool,
    pub no_overwrite: bool,
    pub keep_newer: bool,
    pub no_directory: bool,
    pub strip_components: u32,
    pub includes: GlobSet,
    pub excludes: GlobSet,
    pub backup_suffix: Option<String>,
    pub preserve_permissions: bool,
    /// Restore owner/group on extracted entries (tar-family only).
    pub same_owner: bool,
    /// Extract only entries with mtime strictly greater than this (unix seconds).
    pub newer_than: Option<i64>,
    /// Extract only entries with mtime strictly less than this (unix seconds).
    pub older_than: Option<i64>,
    /// Substring rename rules applied to each entry path after strip_components.
    /// Each `(old, new)` is applied in order; all occurrences of `old` are replaced.
    pub renames: Vec<(String, String)>,
    /// Prefix prepended to every entry path after renames.
    pub prefix: Option<Utf8PathBuf>,
    pub progress: &'a dyn ProgressReport,
    /// Password for decrypting the archive (zip and 7z only).
    pub password: Option<String>,
}

impl CompressOpts<'_> {
    /// Construct opts with no progress reporting (for tests / programmatic use).
    pub fn new(level: Option<u32>, excludes: GlobSet) -> CompressOpts<'static> {
        CompressOpts {
            level,
            excludes,
            follow_symlinks: false,
            exclude_vcs_ignores: false,
            no_recursion: false,
            progress: &NoProgress,
            fixed_mtime: None,
            fixed_uid: None,
            fixed_gid: None,
            fixed_mode: None,
            newer_than: None,
            older_than: None,
            ignore_failed_read: false,
            password: None,
        }
    }
}

impl DecompressOpts<'_> {
    /// Construct opts with no progress reporting (for tests / programmatic use).
    pub fn new(
        force: bool,
        strip_components: u32,
        includes: GlobSet,
        excludes: GlobSet,
    ) -> DecompressOpts<'static> {
        DecompressOpts {
            force,
            no_overwrite: false,
            keep_newer: false,
            no_directory: false,
            strip_components,
            includes,
            excludes,
            backup_suffix: None,
            preserve_permissions: false,
            same_owner: false,
            newer_than: None,
            older_than: None,
            renames: Vec::new(),
            prefix: None,
            progress: &NoProgress,
            password: None,
        }
    }
}