smol-tar
A minimal async streaming tar reader/writer for smol or tokio I/O.
Reading uses a streaming state machine, so the archive never needs to be fully
buffered, while writing uses a compact staging buffer with backpressure via
Sink.
Supported formats
Reads:
- Old tar
- GNU tar
- POSIX ustar/pax
- GNU long names and long links
- PAX path metadata, timestamps, numeric ids, sizes, and extended attributes
Writes:
- POSIX ustar/pax
- PAX records for long paths, long link targets, timestamps, numeric ids, symbolic names, sizes, and extended attributes
Installation
[]
= "0.1"
[]
= { = "0.1", = false, = ["tokio"] }
Reading archives
use ;
use ;
let data = new;
let mut tar = new;
while let Some = tar.next.await
Regular file bodies are streamed. To continue to the next entry, either consume the file body fully or drop the file reader.
Writing archives
use Cursor;
use ;
let sink = new;
let mut tar = new;
tar.write.await?;
let body = new;
tar.write
.await?;
tar.finish.await?;
Finishing the writer emits the two zero blocks required to terminate a tar
archive. The Sink implementation remains available when you want to compose a
writer with Stream/TryStream adapters.
TarWriter::new(...) usually infers its file-reader type from the file entries
you send later. If you only send metadata-only entries such as directories, you
may need an explicit type annotation; the rustdoc for TarWriter shows that
form.
Filtering one archive into another sink
use ;
use Cursor;
use ;
let mut input = new;
let mut source = new;
source
.send
.await?;
source
.send
.await?;
source
.send
.await?;
source
.send
.await?;
source.close.await?;
input.set_position;
let mut output = new;
let mut filtered = new;
new
.try_filter
.forward
.await?;
filtered.close.await?;
output.set_position;
let paths: = new
.map_ok
.try_collect
.await?;
assert_eq!;
Example CLI
The repository also ships a feature-gated example CLI in
examples/smol-tar-bin.
Rationale
For one of my projects, I needed an asynchronous streaming library for reading
and writing tar archives. Since the project was based on async-std (now
smol),
tokio-tar was out of scope, so I
started using async-tar. Later, I
needed to add some functionality, but the depth and number of abstractions in
async-tar exceeded my cognitive capacity, so I quickly put together a simple,
manageable state machine.
The library is properly fuzzed and covered by tests. It has also seen heavy use in a real internal CI/CD pipeline for a while, and now seems ready to be released.
Caveats
- Regular file bodies are streamed. To advance to the next entry, fully consume the file body or drop the file reader.
- Library paths and example-CLI paths are UTF-8 only.
LICENSE
MIT