-
Notifications
You must be signed in to change notification settings - Fork 29
feat(compressors): add streaming compression crate #722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
martintmk
merged 104 commits into
main
from
user/martintomka/20260901-add-compressors-crate
Sep 11, 2026
Merged
Changes from all commits
Commits
Show all changes
104 commits
Select commit
Hold shift + click to select a range
f61d816
feat(compressors): add streaming compression crate
martintmk 7f14112
fix(compressors): preserve binary gzip fixtures
martintmk a9fd437
docs(compressors): align imported documentation
martintmk eb8c99e
test(compressors): reach 100% coverage and fix all surviving mutants
martintmk f3b97c2
refactor(compressors): share builders, traits and resources across fo…
martintmk 5b47776
refactor(compressors): fold flush into Compression and drop the split…
martintmk 8bc7326
refactor(compressors): make compress and decompress crate-level funct…
martintmk 9fdd4c6
refactor(compressors): lift Format to the crate root
martintmk d06079a
refactor(compressors): drop the per-format builder aliases
martintmk ec3e895
refactor(compressors): rename DecompressionLimits to DecompressorLimits
martintmk 007dcc1
refactor(compressors): move Output into core
martintmk db3e585
docs(compressors): hide the Compression methods as an internal detail
martintmk b5742b3
feat(compressors)!: enable no format by default
martintmk 747792f
docs(compressors): lead with the high-level API and trim Security
martintmk 04a90de
fix(compressors): satisfy the nightly formatter and close the coverag…
martintmk 17f82b1
review(compressors): use the tick crate for the example's timer
martintmk 3162647
docs(compressors): regenerate the README after the doc-comment reformat
martintmk 821ad48
fix(compressors): stop dropping pooled engines inside Drop
martintmk b1a8dc1
ci(compressors): exclude the crate from the Miri check
martintmk 05ec5ee
fix(compressors)!: bound the buffering conveniences and tighten codec…
martintmk 82ec1fd
ci: exclude compressors from the extended-analysis Miri step
martintmk f20f008
review(compressors): drop the unused CompressionStream::into_parts API
martintmk ee50634
review(compressors): lead the crate docs with bytesbuf, pooling and t…
martintmk d549ff3
review(compressors): move the driving methods to a sealed Compression…
martintmk 1ea798e
review(compressors): hide CompressionInternal behind a pub(crate) module
martintmk 0cd5109
review(compressors): implement recoverable::Recovery on Error
martintmk e807273
review(compressors): keep Output out of the public API
martintmk d6432c7
test(compressors): assert the wrapped cause renders, restoring 100% c…
martintmk 15a94b7
style(compressors): apply nightly rustfmt to the reviewed changes
martintmk a3bb149
test(compressors): tighten the drain-loop step cap so spinning mutant…
martintmk 000a210
review(compressors): fix duplicated cfg gates and misleading builder …
martintmk 69a6eb3
fix(compressors): clamp the zstd output fill mark and exclude test mo…
martintmk 4a9f6fa
Merge branch 'main' into user/martintomka/20260901-add-compressors-crate
martintmk 608a135
fix(compressors): end the stream when a codec asks for input after en…
martintmk 67be047
merge: integrate the updated PR branch head
martintmk e9a9763
fix(compressors): gate gzip doctests, correct recovery and brotli qua…
martintmk 9c68a71
feat(compressors)!: give the format module the shape every other form…
martintmk a81a13a
fix(compressors): unbreak the docs job and address the review's high-…
martintmk 52eb54f
fix(compressors)!: reject trailing data after a single stream by default
martintmk 7666761
chore(compressors): address the review's manifest, workflow and index…
martintmk fd3dc6a
perf(compressors): pool zstd contexts by nothing and reserve output l…
martintmk 35df0d1
docs(compressors): tighten the benchmark documentation and methodology
martintmk 1a62813
docs(compressors): enable docs.rs feature badges and correct several …
martintmk 4ce506d
fix(compressors): decode brotli in strict RFC 7932 mode
martintmk 59af4e2
review: tighten format test step cap to 10,000
martintmk befe349
perf: inline non-generic exported constructors and conversions
martintmk 5547bbd
perf: inline the remaining non-generic forwarding wrappers
martintmk 22fb419
docs: settle on "engine" as the single term and simplify pool docs
martintmk c358339
docs(compressors): thread one Resources through the round-trip example
martintmk 5a10200
test(compressors): correct the false SAFETY note on the Overreports f…
martintmk 0683502
docs(compressors): frame cold error paths as external-contract defence
martintmk ffaee88
docs(compressors): tie the decompression output cap to retained output
martintmk 136a6ed
docs(compressors): keep zstd guidance to what the crate can support
martintmk e764d8a
refactor(compressors): gate optional code on test-or-feature, add tes…
martintmk e58d58c
feat(compressors)!: seal Compression against trait objects
martintmk 404fa63
refactor(compressors)!: drop the with_ prefix from DecompressorLimits…
martintmk e773c26
refactor(compressors)!: rename enable_pooling to with_pool_capacity
martintmk 448e68a
refactor(compressors)!: make brotli compressor construction infallible
martintmk 83d4a96
docs(compressors): add design and implementation guides
martintmk b874272
test(compressors): catch the surviving runtime-format mutants
martintmk b8a1199
docs(compressors): describe what each backend adapter owns
martintmk 6b3cf88
docs(compressors)!: remove the crate-wide broken-link suppression
martintmk a3f1881
perf(compressors): drive the tokio example's clock in simulated time
martintmk 3eb7395
test(compressors): bound the stream test drivers
martintmk 88eac68
merge: integrate origin/main into PR branch
martintmk d1f53d7
docs(compressors): upper-case the guide filenames
martintmk 6eec2f4
feat(compressors)!: implement ThreadAware for Resources
martintmk 5e07a3a
test(compressors): mutation-test the stream polling state machine
martintmk 2dc3e32
fix(compressors): restore the unconditional Level export
martintmk 7272c33
fix(compressors): stop the whole-buffer compress from panicking
martintmk 7f82364
docs(compressors): correct claims the recent API changes invalidated
martintmk bfb37bf
test(compressors): actually exercise the caller's memory provider
martintmk 0939fdf
docs(compressors): stop presenting sealed mechanics as a consumption …
martintmk 1902f63
docs(compressors): record the reasoning behind the zstd policy numbers
martintmk bcfb1e3
test(compressors): say what the cross-format suite actually checks
martintmk a9c07e9
docs(compressors): describe the test modules as the white-box tests t…
martintmk 4cc3980
docs(compressors): limit the error predicates to what they establish
martintmk fcf4f3d
test(compressors): make the fixtures and the zstd window limit carry …
martintmk 2c620be
docs(compressors): keep benchmark observations out of the public cont…
martintmk 68f7818
docs(compressors): record how the tuning defaults were chosen
martintmk 0e8683f
style(compressors): use unwrap in test code per AGENTS.md
martintmk 0bd63d2
Merge branch 'main' into user/martintomka/20260901-add-compressors-crate
martintmk e698431
fix(compressors): hard-fail an out-of-range zstd fill count
martintmk 5e15c7c
merge: integrate the branch's remote main merge
martintmk 605bc2a
feat(compressors)!: default the crate-level decompress to a 64 MiB ce…
martintmk 0128081
refactor(compressors): move the buffering output ceiling into the engine
martintmk 0da1dcb
fix(compressors): repair the no-format build and cut test allocations
martintmk 8089cfc
merge: integrate origin/main into PR branch (auto-resolved .spelling …
martintmk 92d2aa5
test(compressors): exclude the Codec::remaining_output default from m…
martintmk 4dfc067
fix(compressors): restore the buffered stream cap alongside the outpu…
martintmk 396b486
docs(compressors): add a security model guide and a documentation module
martintmk c08c954
test(compressors): add a bounded Bolero campaign over the decompressi…
martintmk d14a50b
test(compressors): make pooling tests control the exact engine they v…
martintmk b2cafe1
test(compressors): name the reuse tests for the property they assert
martintmk f86242b
Merge branch 'main' into user/martintomka/20260901-add-compressors-crate
martintmk f2034b2
test(compressors): cover no-feature encoding rejection
martintmk 276fee0
Merge branch 'main' into user/martintomka/20260901-add-compressors-crate
martintmk 81b8fa9
merge: integrate origin/main into compressors PR
martintmk b57627c
fix: sort merged workspace dependencies
martintmk 3371aed
refactor(compressors): adopt metabench and simplify limit setters
martintmk 1c56ee2
merge: integrate latest origin/main into compressors PR
martintmk fa5ef10
test(compressors): skip timeout-only zstd mutants
martintmk c158624
fix(compressors): make limit setters value-only
martintmk 4601eae
test(compressors): cover exact ratio boundary
martintmk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # Changelog |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # Copyright (c) Microsoft Corporation. | ||
|
martintmk marked this conversation as resolved.
|
||
| # Licensed under the MIT License. | ||
|
|
||
| [package] | ||
| name = "compressors" | ||
|
martintmk marked this conversation as resolved.
|
||
| version = "0.1.0" | ||
| description = "Streaming compression and decompression over bytesbuf byte sequences" | ||
| readme = "README.md" | ||
|
martintmk marked this conversation as resolved.
|
||
| keywords = ["compression", "gzip", "streaming", "zero-copy"] | ||
| categories = ["compression", "network-programming"] | ||
| edition = { workspace = true } | ||
| rust-version = { workspace = true } | ||
| authors = { workspace = true } | ||
| license = { workspace = true } | ||
| homepage = { workspace = true } | ||
| include = { workspace = true } | ||
| repository = "https://github.com/microsoft/oxidizer/tree/main/crates/compressors" | ||
|
|
||
| # Miri cannot run all of this crate's backends. `zstd-safe` binds the native zstd library, and Miri | ||
| # cannot call foreign functions; `flate2`'s `zlib-rs` backend has an open soundness bug that trips | ||
| # Stacked Borrows whenever a Deflate or Inflate is dropped | ||
| # (https://github.com/trifectatechfoundation/zlib-rs/issues/491). Brotli is pure Rust and would run; | ||
| # excluding the whole crate rather than maintaining a brotli-only Miri configuration is a separate | ||
| # decision, taken because the per-format `cfg(miri)` scaffolding the rest would need costs more than | ||
| # the remaining coverage is worth. | ||
| [package.metadata.anvil.miri] | ||
| exclude = true | ||
|
|
||
| [package.metadata.docs.rs] | ||
| all-features = true | ||
|
|
||
| # `cfg_aliases` is used only by `build.rs`. cargo-machete does not scan build | ||
| # scripts, so it reports a false positive; ignore it here. | ||
| [package.metadata.cargo-machete] | ||
| ignored = ["cfg_aliases"] | ||
|
|
||
| [package.metadata.cargo_check_external_types] | ||
| allowed_external_types = [ | ||
| "bytesbuf::*", | ||
| "futures_core::stream::Stream", | ||
| "recoverable::*", | ||
| "thread_aware_core::thread_aware::ThreadAware", | ||
| ] | ||
|
|
||
| [features] | ||
| brotli = ["dep:brotli"] | ||
| # No format is enabled by default: a dependent names the ones it actually speaks, so a build that | ||
| # only needs brotli never compiles flate2, and vice versa. A build with no format at all still gets | ||
| # the shared contract and builders, which is what a crate that only re-exports them needs. | ||
| default = [] | ||
| deflate = ["dep:flate2"] | ||
| futures-stream = ["dep:futures-core", "dep:pin-project-lite"] | ||
| gzip = ["dep:flate2"] | ||
| zlib = ["dep:flate2"] | ||
| zstd = ["dep:zstd-safe"] | ||
|
|
||
| [dependencies] | ||
| brotli = { workspace = true, features = ["std"], optional = true } | ||
| bytesbuf = { workspace = true, features = ["std"] } | ||
| # `zlib-rs` rather than flate2's default `miniz_oxide`: it is the fastest of flate2's backends and, | ||
| # unlike the `zlib`/`zlib-ng` bindings, is pure Rust, so the deflate family stays free of C on a path | ||
| # that parses untrusted input. The cost is recorded above -- it is what keeps this crate out of Miri. | ||
| flate2 = { workspace = true, features = ["zlib-rs"], optional = true } | ||
|
martintmk marked this conversation as resolved.
martintmk marked this conversation as resolved.
|
||
| futures-core = { workspace = true, optional = true } | ||
| pin-project-lite = { workspace = true, optional = true } | ||
| recoverable = { workspace = true } | ||
| thread_aware = { workspace = true, features = ["std"] } | ||
| zstd-safe = { workspace = true, features = ["std"], optional = true } | ||
|
|
||
| [build-dependencies] | ||
| cfg_aliases = { workspace = true } | ||
|
|
||
| [dev-dependencies] | ||
| bolero = { workspace = true, features = ["std"] } | ||
| brotli = { workspace = true, features = ["std"] } | ||
| bytesbuf = { workspace = true, features = ["std", "test-util"] } | ||
| criterion = { workspace = true } | ||
| flate2 = { workspace = true, features = ["zlib-rs"] } | ||
| futures = { workspace = true, features = ["executor"] } | ||
| futures-core = { workspace = true } | ||
| metabench = { workspace = true } | ||
| mutants = { workspace = true } | ||
| pin-project-lite = { workspace = true } | ||
| thread_aware = { path = "../thread_aware", default-features = false, features = ["std", "test-utils"] } | ||
| tick = { path = "../tick", features = ["tokio", "test-util"] } | ||
| tokio = { workspace = true, features = ["rt-multi-thread", "macros", "time", "sync"] } | ||
| tokio-stream = { workspace = true } | ||
| zstd-safe = { workspace = true, features = ["std"] } | ||
|
|
||
| [[example]] | ||
| name = "round_trip" | ||
| required-features = ["brotli", "deflate", "gzip", "zlib", "zstd"] | ||
|
|
||
| [[example]] | ||
| name = "tokio_stream" | ||
| required-features = ["futures-stream", "gzip"] | ||
|
|
||
| [[bench]] | ||
| harness = false | ||
| name = "compressors_codec" | ||
| required-features = ["brotli", "deflate", "futures-stream", "gzip", "zlib", "zstd"] | ||
|
|
||
| [lints] | ||
| workspace = true | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.