totebag 0.9.0

An API for extracting/archiving files and directories in multiple formats.
Documentation

API of totebag crate

:speaking_head: Overview

This is the README for the totebag crate, which provides the API of the totebag tool for extracting/archiving files and directories in multiple formats.

The totebag crate provides a unified API for handling various archive formats, making it easy for developers to integrate archiving and extraction functionality into their Rust applications. It abstracts the differences between various archive formats, providing a consistent interface for working with archives.

Every default dependency is a pure Rust implementation, so building totebag requires no C toolchain and cross-compiling needs nothing but a Rust target.

Supported archive formats

Cargo features

Feature Default Effect
clap off Derives clap::ValueEnum for IgnoreType and OutputFormat so they can be used directly as command line arguments.
rar off Enables RAR extraction. See RAR support.
zstd-native off Uses the C zstd library instead of ruzstd. See zstd compression levels.
RAR support

There is no pure Rust RAR implementation. The unrar crate links the C UnRAR library, whose license forbids using its source to re-create the RAR compression algorithm, so RAR is not compiled in by default:

$ totebag -m list some.rar
Rar: support is not compiled in (rebuild with --features rar)

The released binaries and container images are built with --features rar. To get it in your own build, enable the feature:

cargo add totebag --features rar
zstd compression levels

The default zstd backend is ruzstd, which implements the whole decompression side of the specification but only the fastest compression level. .tar.zst archives therefore compress less tightly than zstd(1) would, and the --level option only distinguishes "store" (0) from "compress" (1-9).

Enable zstd-native to link the C library instead and get the full 0-9 range mapped onto zstd's 1-22.

:walking: How to use

:green_heart: Archiving files and directories

use std::path::PathBuf;

let config = totebag::ArchiveConfig::builder()
    .dest("results/test.zip")         // destination file.
    .rebase_dir(PathBuf::from("new")) // prefix for every entry in the archive.
    .overwrite(true)                  // set overwrite flag of the destination file.
    .build();
let targets: Vec<PathBuf> = ["src", "Cargo.toml"].iter() // files to be archived.
    .map(PathBuf::from).collect();
match totebag::archive(&targets, &config) {
    Ok(_) => println!("archiving is done"),
    Err(e) => eprintln!("error: {:?}", e),
}
Entry names

Entry names are normalized by normalize_entry_path before they reach the format backend, so an archive totebag creates never contains a name that starts at the filesystem root or climbs out with ..:

use std::path::{Path, PathBuf};
use totebag::normalize_entry_path;

assert_eq!(normalize_entry_path(Path::new("../project/src/main.rs")), PathBuf::from("project/src/main.rs"));
assert_eq!(normalize_entry_path(Path::new("/etc/hosts")), PathBuf::from("etc/hosts"));
assert_eq!(normalize_entry_path(Path::new("./src/main.rs")), PathBuf::from("src/main.rs"));

rebase_dir is applied on top of the normalized path.

:yellow_heart: Extracting the archive file

let config = totebag::ExtractConfig::builder()
    .dest("results") // set the destination directory.
    .build();
match totebag::extract("extracting_archive_file.zip", &config) {
    Ok(r) => println!("{:?}", r),
    Err(e) => println!("error: {:?}", e),
}
Compression level
Level
Ar N/A
Cab 0: None, otherwise: MsZIP; see CompressionType.
Cpio 0-3: Odc, 4-6: Newc, 7: Crc, 8: Bin(LittleEndian), 9: Bin(BigEndian); see kpea::Format.
Gzip Passed through as-is; see Compression.
Bzip2 Passed through as-is; see Compression.
Xz Used as the preset; see XzOptions::with_preset.
Zstd 0: stored, 1-9: fastest. With zstd-native, mapped onto zstd's 1-22; see Encoder.
Zip 0: No compression, 1-3: Deflate (10, 24, 264), 4-6: Bzip2 (1, 6, 9), 7-9: Xz (3, 6, 9); see FileOptions.
7z 0-4: LZMA, 5-9: LZMA2; see EncoderMethod.

:blue_heart: List entries in an archive file

The list function returns a string-formatted list of entries in the archive file.

use totebag::{ListConfig, OutputFormat, format::default_format_detector};

let config = ListConfig::new(OutputFormat::Default, default_format_detector());
match totebag::list("listing_archive_file.zip", &config) {
    Ok(formatted_list) => println!("{}", formatted_list),
    Err(e) => println!("error: {:?}", e),
}

The entries function returns the entries recorded in the archive file.

use totebag::format::default_format_detector;

let detector = default_format_detector();
match totebag::entries("listing_archive_file.zip", detector.as_ref()) {
    Ok(entries) => {
        for entry in entries.iter() {
            println!("{}", entry.name);
        }
    }
    Err(e) => println!("error: {:?}", e),
}