diff --git a/Cargo.toml b/Cargo.toml index 4b83ffb6..d41209c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,11 @@ libz-ng-sys = { version = "1.1.16", optional = true } # this matches the default features, but we don't want to depend on the default features staying the same zlib-rs = { version = "0.5.3", optional = true, default-features = false, features = ["std", "rust-allocator"] } cloudflare-zlib-sys = { version = "0.3.6", optional = true } +## This implementation uses only safe Rust code and doesn't require a C compiler. +## It provides good performance for most use cases while being completely portable. miniz_oxide = { version = "0.8.5", optional = true, default-features = false, features = ["with-alloc", "simd"] } crc32fast = "1.2.0" +document-features = { version = "0.2", optional = true } [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] miniz_oxide = { version = "0.8.5", default-features = false, features = ["with-alloc", "simd"] } @@ -36,17 +39,75 @@ rand = "0.9" quickcheck = { version = "1.0", default-features = false } [features] +## The default backend using pure Rust implementation via miniz_oxide. +## This provides a safe, portable compression implementation without requiring a C compiler. default = ["rust_backend"] -any_zlib = ["any_impl"] # note: this is not a real user-facing feature -any_impl = [] # note: this is not a real user-facing feature + +#! ### User-Facing Backend Features +#! Choose one of these features to select the compression backend. +#! Only one backend should be enabled at a time, or else one will see an unstable order which is currently +#! `zlib-ng`, `zlib-rs`, `cloudflare_zlib`, `miniz_oxide` and which may change at any time. + +## Use the zlib-rs backend, a pure Rust rewrite of zlib. +## This is the fastest backend overall, providing excellent performance with some `unsafe` code. +## It does not require a C compiler but uses `unsafe` Rust for optimization. +zlib-rs = ["any_impl", "dep:zlib-rs"] + +## Use the pure Rust `miniz_oxide` backend (default). +## This implementation uses only safe Rust code and doesn't require a C compiler. +## It provides good performance for most use cases while being completely portable. +## +## Note that this feature at some point may be switched to use `zlib-rs` instead. +rust_backend = ["miniz_oxide", "any_impl"] + +## Use the system's installed zlib library. +## This is useful when you need compatibility with other C code that uses zlib, +## or when you want to use the system-provided zlib for consistency. zlib = ["any_zlib", "libz-sys"] + +## Use the system's installed zlib library with default features enabled. +## Similar to `zlib` but enables additional features from libz-sys. zlib-default = ["any_zlib", "libz-sys/default"] + +## Use zlib-ng in zlib-compat mode via libz-sys. +## This provides zlib-ng's performance improvements while maintaining compatibility. +## Note: If any crate in your dependency graph uses stock zlib, you'll get stock zlib instead. +## For guaranteed zlib-ng, use the `zlib-ng` feature. +## When using this feature, if any crate in your dependency graph explicitly requests stock zlib, +## or uses libz-sys directly without `default-features = false`, you'll get stock zlib rather than zlib-ng. +## See [the libz-sys README](https://github.com/rust-lang/libz-sys/blob/main/README.md) for details. +## To avoid that, use the `"zlib-ng"` feature instead. + zlib-ng-compat = ["zlib", "libz-sys/zlib-ng"] + +## Use the high-performance zlib-ng library directly. +## This typically provides better performance than stock zlib and works even when +## other dependencies use zlib. Requires a C compiler. zlib-ng = ["any_zlib", "libz-ng-sys"] -zlib-rs = ["any_impl", "dep:zlib-rs"] + +## Use Cloudflare's optimized zlib implementation. +## This provides better performance than stock zlib on x86-64 (with SSE 4.2) and ARM64 (with NEON & CRC). +## * ⚠ Does not support 32-bit CPUs and is incompatible with mingw. +## * ⚠ May cause conflicts if other crates use different zlib versions. cloudflare_zlib = ["any_zlib", "cloudflare-zlib-sys"] -rust_backend = ["miniz_oxide", "any_impl"] -miniz-sys = ["rust_backend"] # For backwards compatibility + +## Deprecated alias for `rust_backend`, provided for backwards compatibility. +## Use `rust_backend` instead. +miniz-sys = ["rust_backend"] + +#! ### Internal Features +#! These features are used internally for backend selection and should not be enabled directly by users. +#! They are documented here to aid with maintenance. + +## **Internal:** Marker feature indicating that any zlib-based C backend is enabled. +## This is automatically enabled by `zlib`, `zlib-ng`, `zlib-ng-compat`, or `cloudflare_zlib`. +## Do not enable this feature directly; instead, choose a specific backend feature. +any_zlib = ["any_impl"] + +## **Internal:** Marker feature indicating that any compression backend is enabled. +## This is automatically enabled by all backend features to ensure at least one implementation is available. +## Do not enable this feature directly; instead, choose a specific backend feature. +any_impl = [] [package.metadata.docs.rs] all-features = true diff --git a/src/lib.rs b/src/lib.rs index faf46658..08033ded 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,12 +14,15 @@ //! # Implementation //! //! In addition to supporting three formats, this crate supports several different -//! backends, controlled through this crate's features: +//! backends, controlled through this crate's *features flags*: //! -//! * `default`, or `rust_backend` - this implementation uses the `miniz_oxide` +//! * `default`, or `rust_backend` - this implementation currently uses the `miniz_oxide` //! crate which is a port of `miniz.c` to Rust. This feature does not //! require a C compiler, and only uses safe Rust code. //! +//! Note that the `rust_backend` feature may at some point be switched to use `zlib-rs`, +//! and that `miniz_oxide` should be used explicitly if this is not desired. +//! //! * `zlib-rs` - this implementation utilizes the `zlib-rs` crate, a Rust rewrite of zlib. //! This backend is the fastest, at the cost of some `unsafe` Rust code. //! @@ -30,6 +33,23 @@ //! //! The `zlib-rs` backend typically outperforms all the C implementations. //! +//! # Feature Flags +#![cfg_attr( + not(feature = "document-features"), + doc = "Activate the `document-features` cargo feature to see feature docs here" +)] +#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] +//! +//! ## Ambiguous feature selection +//! +//! As Cargo features are additive, while backends are not, there is an order in which backends +//! become active if multiple are selected. +//! +//! * zlib-ng +//! * zlib-rs +//! * cloudflare_zlib +//! * miniz_oxide +//! //! # Organization //! //! This crate consists of three main modules: `bufread`, `read`, and `write`. Each module