Large, independent feature sets#

Scenario: a codec crate supports several serialization formats and, independently, several compression codecs. The two axes are orthogonal — the format code doesn’t care which codec is enabled — so a full powerset over all six features is mostly redundant.

[package]
name = "codec"
version = "0.1.0"
edition = "2024"

[features]
json = []
yaml = []
msgpack = []
gzip = []
zstd = []
brotli = []

[package.metadata.cargo-fc]
# Formats and compression codecs are independent axes — powerset within each
# group, never across them.
isolated_feature_sets = [
  ["json", "yaml", "msgpack"],
  ["gzip", "zstd", "brotli"],
]

[workspace]

Instead of one powerset over all six features, cargo fc builds a sub-matrix per group and merges them: the formats are varied among themselves, the codecs among themselves — but the two are never crossed. A combination appearing in more than one group is kept once.

This turns multiplicative growth into additive growth. The full powerset would be 2⁶ = 64 combinations; the isolated sets reduce it to 2³ + 2³ − 1 = 15 (the shared empty set is merged):

$ cargo fc --summary-only check
 
     Checking [ 1/15] codec ( features = [] )
     Checking [ 2/15] codec ( features = [brotli] )
     Checking [ 3/15] codec ( features = [brotli, gzip] )
     Checking [ 4/15] codec ( features = [brotli, gzip, zstd] )
     Checking [ 5/15] codec ( features = [brotli, zstd] )
     Checking [ 6/15] codec ( features = [gzip] )
     Checking [ 7/15] codec ( features = [gzip, zstd] )
     Checking [ 8/15] codec ( features = [json] )
     Checking [ 9/15] codec ( features = [json, msgpack] )
     Checking [10/15] codec ( features = [json, msgpack, yaml] )
     Checking [11/15] codec ( features = [json, yaml] )
     Checking [12/15] codec ( features = [msgpack] )
     Checking [13/15] codec ( features = [msgpack, yaml] )
     Checking [14/15] codec ( features = [yaml] )
     Checking [15/15] codec ( features = [zstd] )
 
    Finished 15 feature combinations for 1 package in 0.00s
 
        PASS codec ( 0 errors, 0 warnings, features = [] )
        PASS codec ( 0 errors, 0 warnings, features = [brotli] )
        PASS codec ( 0 errors, 0 warnings, features = [brotli, gzip] )
        PASS codec ( 0 errors, 0 warnings, features = [brotli, gzip, zstd] )
        PASS codec ( 0 errors, 0 warnings, features = [brotli, zstd] )
        PASS codec ( 0 errors, 0 warnings, features = [gzip] )
        PASS codec ( 0 errors, 0 warnings, features = [gzip, zstd] )
        PASS codec ( 0 errors, 0 warnings, features = [json] )
        PASS codec ( 0 errors, 0 warnings, features = [json, msgpack] )
        PASS codec ( 0 errors, 0 warnings, features = [json, msgpack, yaml] )
        PASS codec ( 0 errors, 0 warnings, features = [json, yaml] )
        PASS codec ( 0 errors, 0 warnings, features = [msgpack] )
        PASS codec ( 0 errors, 0 warnings, features = [msgpack, yaml] )
        PASS codec ( 0 errors, 0 warnings, features = [yaml] )
        PASS codec ( 0 errors, 0 warnings, features = [zstd] )

When to raise the safety limit#

cargo fc refuses to generate more than max_combinations (default 100000). If you have a legitimately large but bounded matrix, raise it:

[package.metadata.cargo-fc]
max_combinations = 250000

If you hit the limit unexpectedly, that’s usually a sign the matrix should be shaped with isolated_feature_sets, only_features, or skip_optional_dependencies rather than simply raised.

See isolated_feature_sets.