noflate
Use this skill when integrating noflate into Rust code. Focus on the crate's
actual API shape and usage patterns, not generic compression background.
What this crate exposes
noflate::deflatefor raw DEFLATE (RFC 1951)noflate::gzipfor GZIP (RFC 1952), plusCrc32/crc32noflate::zlibfor ZLIB (RFC 1950), plusAdler32/adler32- Shared root types:
Error,Result,Format
Each format module exposes the same main shape:
- One-shot helpers:
compress(data) -> Result<Vec<u8>>,decompress(data) -> Result<Vec<u8>> - Streaming types:
Encoder,Decoder
Choosing the right API
- Pick
deflate,gzip, orzlibbased on the wire format you need. - Use
compress/decompressfor one-shot data. - Use
Encoder/Decoderwhen data arrives incrementally or output must be consumed in chunks. - Use
EncodeOptionswhen you need fixed Huffman blocks, stored blocks, or buffering control.
Usage gotchas
- This crate is
#![no_std]; it requiresalloc, notstd. - The streaming API is sans-io:
feed(data)pushes input,output()borrows produced bytes,advance(n)marks bytes as consumed. - One-shot compression uses buffered input internally; for similar behavior in
streaming code, use
EncodeOptions::new().buffer_all_input(). sync_flush()is for continuing a DEFLATE stream across message boundaries. It is useful forpermessage-deflate; do not treat it likefinish().reset_history()is only forno_context_takeoverstyle flows. Do not reset state between messages unless the protocol requires it.Format::detect(&data)needs enough prefix bytes to distinguish framing; it returnsNonefor too-short input.- Checksum helpers are format-specific: gzip uses CRC-32, zlib uses Adler-32.
API patterns to preserve
One-shot:
let compressed = noflate::deflate::compress(b"hello")?;
let decompressed = noflate::deflate::decompress(&compressed)?;
Streaming encoder:
let mut enc = noflate::deflate::Encoder::new();
enc.feed(b"chunk1")?;
enc.feed(b"chunk2")?;
enc.finish()?;
let out = enc.output().to_vec();
enc.advance(out.len());
Streaming decoder:
let mut dec = noflate::deflate::Decoder::new();
dec.feed(&compressed)?;
let out = dec.output().to_vec();
dec.advance(out.len());
assert!(dec.is_finished());
Options:
use noflate::deflate::EncodeOptions;
let dynamic = EncodeOptions::new();
let fixed = EncodeOptions::new().fixed_huffman();
let stored = EncodeOptions::new().stored();
let buffered = EncodeOptions::new().buffer_all_input();
let limited = EncodeOptions::new().max_block_input_bytes(32 * 1024);
WebSocket permessage-deflate:
let mut enc = noflate::deflate::Encoder::new();
enc.feed(message)?;
enc.sync_flush()?;
let frame = enc.output().to_vec();
enc.advance(frame.len());
// Per RFC 7692, strip the trailing 0x00 0x00 0xFF 0xFF before sending.
enc.reset_history(); // only when no_context_takeover is negotiated
Format detection:
match noflate::Format::detect(&data) {
Some(noflate::Format::Gzip) => {}
Some(noflate::Format::Zlib) => {}
Some(noflate::Format::Deflate) => {}
None => {}
}
Practical hints
- If you already have all input bytes, start with
compress/decompressbefore reaching for the streaming API. - If you use the streaming API, always drain
output()and calladvance()after consuming bytes. - For WebSocket
permessage-deflate, strip the final0x00 0x00 0xFF 0xFFaftersync_flush(). EncodeOptionsbelongs tonoflate::deflate, but the same options are used bygzip::Encoderandzlib::Encoder.- The crate performs no I/O itself, but the sans-io API plugs into
std::io::Write/Readwith a small adapter:Write::writeforwards tofeedand drainsoutputinto the inner sink;Read::readpulls fromoutputand tops up viafeedfrom the inner source. Seeexamples/io_bridge.rsfor a runnableDeflateWriter/DeflateReaderpair.