Safe-Rust archive reading, writing, compression, and extraction.
This project is independent of the upstream libarchive project. It is not a binding. Project-owned crates forbid unsafe code. The default codec profile is C/FFI-free; an explicit native performance profile is also available. See Codec backends.
| Format | Current read support | Current write support | Important limits |
|---|---|---|---|
| tar | sequential v7/ustar/pax/GNU | sequential | known-size entries; GNU sparse supported |
| cpio | sequential binary/odc/newc/crc | sequential | known-size entries |
| ar | sequential GNU/BSD | sequential | thin references are identified, never followed |
| ZIP/ZIP64 | seek or streaming, Store/Deflate/BZip2/Zstandard/LZMA | streaming with descriptors (Zstandard write is native-codecs only) | optional WinZip AES; no Deflate64 method yet |
| 7z | seek, LZMA/LZMA2 | seek | optional sevenz; single folder; no general coder graph |
| ISO 9660 | seek, Rock Ridge/Joliet | seek | no UDF |
| Outer compression | Decode | Encode | Current backend note |
|---|---|---|---|
| gzip/DEFLATE | yes | yes | portable miniz_oxide; native libz |
| bzip2 | yes | yes | portable libbz2-rs-sys; native libbz2 |
| zstd | yes | yes | portable ruzstd; native libzstd |
| xz/LZMA2 | yes | yes | portable lzma-rust2; native liblzma |
| LZ4 frame | yes | yes | portable lz4_flex; native liblz4 |
The detailed support matrix distinguishes archive dialects, compression methods, encryption, metadata, and unsupported cases. The Modern Replacement roadmap defines the larger goal without presenting planned formats as implemented.
[dependencies]
libarchive_oxide = "0.2"For no_std:
[dependencies]
libarchive_oxide-core = "0.2"CLI tools:
cargo install libarchive_oxide-cli --locked
# Unified safe workflow
oxarchive inspect artifact.tar.zst
oxarchive plan --json artifact.zip
oxarchive apply artifact.tar.gz destination
oxarchive create --format tar --filter zstd artifact.tar.zst input/
oxarchive verify artifact.7zoxarchive uses the high-level session engine. Its JSON plan is an advisory
report and is deliberately not accepted back by apply; application always
plans and applies the same immutable input snapshot in one process. Inspection
uses flushed, schema-versioned JSON Lines directly from ReaderEvent, and
creation shares ArchiveEngine, CreateOptions, finite limits, and the safe
filesystem walker. File archives are staged and published without replacement;
stdout archives remain explicit binary streams.
ArchiveEngine is the preferred safe application surface. Opening a session
creates a bounded immutable snapshot, so an ExtractionPlan cannot be applied
to a different input. Collected inspection is metadata-budgeted; callers can
use ArchiveSession::next_event instead when they need constant-memory event
processing.
use std::io::Read;
use libarchive_oxide::ArchiveEngine;
fn inspect(input: impl Read) -> Result<(), Box<dyn std::error::Error>> {
let mut session = ArchiveEngine::new().open(input)?;
let inspection = session.inspect()?;
println!("{:?}: {} entries", inspection.format(), inspection.entries().len());
Ok(())
}use std::io::Read;
use libarchive_oxide::{ArchiveReader, ReaderEvent};
fn list(input: impl Read) -> Result<(), Box<dyn std::error::Error>> {
let mut archive = ArchiveReader::new(input);
loop {
match archive.next_event()? {
ReaderEvent::Entry(metadata) => {
println!("{}", metadata.path().display_lossy());
}
ReaderEvent::Done => break,
_ => {}
}
}
Ok(())
}| Feature | Default | Enables |
|---|---|---|
portable-codecs |
yes | all five outer codecs through C/FFI-free backends |
native-codecs |
no | all five outer codecs through native libraries; requires --no-default-features |
gzip |
via profile | gzip; portable when selected alone |
bzip2 |
via profile | bzip2; portable when selected alone |
zstd |
via profile | zstd; portable when selected alone |
xz |
via profile | xz; portable when selected alone |
lz4 |
via profile | LZ4 frame; portable when selected alone |
aes |
no | WinZip AES-256 AE-2 |
sevenz |
no | 7z |
async |
no | runtime-neutral futures-io adapters |
tokio |
no | Tokio I/O adapters |
Sequential I/O uses ArchiveReader / ArchiveWriter; seek-required formats
use SeekArchiveReader / SeekArchiveWriter. The async feature adds both
AsyncArchive* and AsyncSeekArchive*, while tokio adds the corresponding
TokioArchive*, TokioSeekArchive*, and bounded TokioExtractor adapters.
Pipeline is the direct caller-driven API and incrementally composes up to the
configured number of gzip, bzip2, zstd, xz, and lz4 layers.
Downstream crates can prepend statically dispatched FormatProvider and
CodecProvider implementations to ProviderSet::builtins(), or start from a
closed ProviderSet::empty(). Pipeline, ArchiveReader, and ArchiveEngine
then use that same concrete chain for events, inspection, rewind, planning,
apply, and create_registered; no global registry, dyn dispatch, or plugin
ABI is introduced. Providers serve stable FormatId / FilterId values, and
prepend order selects an alternative implementation. See the
provider contract.
ArchiveSession::apply_with_adapter keeps session identity, path policy,
resource limits, hardlink ordering, and archive events in the engine while a
compile-time FilesystemAdapter performs normalized relative operations.
ApplyReport::filesystem_findings records applied, unsupported, refused,
partial, and OS-error outcomes for every requested entry or metadata operation;
an adapter cannot silently omit an advertised attribute. Existing
apply(plan, cap_std::fs::Dir) remains a shortcut to the built-in atomic
CapStdFilesystemAdapter. Linux additionally restores descriptor-based
mode/time, numeric ownership, xattrs, POSIX ACLs, and sparse layout. See the
filesystem adapter contract.
libarchive_oxide-core is zero-dependency no_std + alloc safe Rust, and all
project-owned crates use #![forbid(unsafe_code)]. portable-codecs is the
default and its normal/build graph rejects codec C/FFI packages. Select the
native performance profile explicitly with
--no-default-features --features native-codecs. The two profile markers are
mutually exclusive; individual codec features without a marker remain portable
for compatibility. Both profiles drive the same bounded state-machine contract
and corpus. See the profile evidence.
| Crate | MSRV |
|---|---|
libarchive_oxide-core |
Rust 1.85 |
libarchive_oxide |
Rust 1.87 |
libarchive_oxide-cli |
Rust 1.87 |
All published crates use #![forbid(unsafe_code)].
- API documentation
- CLI reference
- Security policy
- Contributing
- Architecture decisions
- Compile-time provider contract
- Filesystem adapter contract
- CLI and streaming-output contract
- Detailed support matrix
- Modern Replacement roadmap
- Modern Replacement issue tracker
- v0.1 → v0.2 migration
Licensed under either MIT or Apache-2.0, at your option.