Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

no_std feature boundary

no_std is opt-in and disabled by default. The default std feature enables standard-library support in fearless_simd and thiserror. To build for a target without std, depend on mbrotli with default-features = false and features = ["no_std", "compression", "decompression"] (or select just one codec). The library uses #![no_std] and extern crate alloc; applications supply a global allocator. This is not allocation-free compression.

The no_std feature enables the optional libm dependency and fearless_simd/libm; ordinary std builds enable neither. Select std or no_std when disabling default features so fearless_simd has a math provider.

Cargo features are additive. no_std overrides the library’s std-only API and instrumentation gates even if std or profiling features are also enabled, but cannot remove dependencies enabled by those features. Bare-metal applications must omit std and every hotpath* feature (hotpath, hotpath-cpu, hotpath-alloc, hotpath-callgrind, hotpath-cloud) throughout their resolved dependency graph. Disabling defaults alone does not select no_std.

flowchart TD
    Feature{no_std enabled?}
    Feature -->|no| Std[std API: I/O, parallel tasks, framed adapters]
    Feature -->|yes| Alloc[core + alloc: compressor, sessions, dictionaries]
    Feature -->|yes| Portable[enable libm and fearless_simd/libm]
    Std --> Engine[private compressor::core encoder state machines]
    Alloc --> Engine
    Feature -->|no| Detect[runtime SIMD detection when dependency std is enabled]
    Feature -->|yes| Baseline[compile-time SIMD baseline]
    Detect --> Dispatch[one retained kernel selection]
    Baseline --> Dispatch
    Dispatch --> Engine
    Engine --> Log{logarithm beyond table}
    Log -->|std mode| Native[f64::log2]
    Log -->|no_std mode| Libm[libm::log2]

API and ownership

When compression is enabled, the compressor, configuration, high-level errors, retained workspace, slice and vector output, incremental sessions, and prepared dictionaries remain available. Experimental serialized dictionaries and stream offsets also remain available with experimental. Their ownership, state transitions, progress accounting, reset behavior, and error propagation are unchanged. Owned buffers use alloc; formatting, range operations, and error traits use core.

The io module, its compressor reader/writer constructors, the conversion from EncodeError to std::io::Error, and the private I/O error variant are omitted. The entire parallel module and its private independent-fragment adapter are omitted because they depend on I/O, files, synchronization, clocks, and unwinding. Framed writer/reader adapters are omitted because they depend on std::io; FramedCompressor, structured input and native sessions remain available with compression,experimental. Codec-neutral framing types and the experimental framed decoder remain available. Hotpath measurement attributes are inactive under no_std.

No new public type or state machine is introduced. Low-level implementation errors remain private; public errors implement core::error::Error through thiserror without requiring std.

SIMD and numeric invariants

Backend::default uses Level::baseline in no_std mode even when feature unification enables std in fearless_simd. Backend::available lists backends supported by that baseline. Compiler target features select the strongest usable level; unsupported targets retain the scalar fallback. Kernel selection remains outside inner loops. Unit tests retain their explicit scalar oracle.

CompressorBuilder::build obtains its default token through Backend::default, so direct construction and explicit backend selection share this policy.

The existing logarithm table is unchanged. Beyond the table, libm::log2 replaces the unavailable standard-library method. The portable result is tested against the host logarithm within floating-point rounding tolerance. Differential tests exercise all qualities against C, including the alloc-only slice/session API. Different math implementations can round differently; exact byte identity across all platforms and math libraries is not guaranteed by the logarithm tolerance.

Verification and known gaps

CI checks the library and experimental dictionaries for thumbv7em-none-eabi, a target with no standard library, and runs host tests with defaults disabled. Default and explicit std-feature tests continue to cover the omitted APIs; --all-features exercises the no_std API because that feature takes precedence. benches/alloc.rs validates and times the alloc-backed one-shot API against C in either feature mode, recording throughput and output size for text, binary, repeated, noisy, small, and large inputs.

tests/no_std.rs covers empty and non-empty output, all qualities, small input/output chunks, flush/finish equivalence with C, dictionary compatibility, errors, and recovery.

Coverage accumulates the full std workspace suite and no_std unit/API tests before enforcing the repository function-coverage threshold.

No allocator-free mode, embedded I/O adapter, or no-std parallel scheduler is implemented. Bare-metal builds are compile-checked; execution tests use a host allocator and the independent C decoder.

Native decoding

With decompression, the alloc-only surface also includes Decompressor, DecoderSession, DecodeDictionary and RAW dictionary views. Serialized/custom mappings follow the same experimental gate in std and alloc profiles. See decoder mechanics and the four-profile compatibility report.

Codec selection is independent of no_std; see codec features.

Structured decoding with alloc

decompression,experimental,no_std exposes framing detection, owner/session, owned/range outputs, metadata and dictionary resolution without compression. Only FramedReader is excluded by no_std precedence.

graph LR
    Alloc[alloc + decompression + experimental] --> Frame[framed owner/session and core]
    Frame --> Raw[existing raw Stream]
    Frame --> Dict[decode-only dictionary preparation]
    Std[not no_std] --> Reader[lending BufRead adapter]
    Reader --> Frame