Skip to content

docs.rs shows the decode and insta items with no feature badge, so optional API reads as unconditional #258

Description

@vyncint

Today — everything behind the decode feature — Bitmap and its methods, DecodeError, and GraphicsPayload::decode — plus the insta re-export and assert_screen_snapshot! behind the insta feature, appears on docs.rs with no indication that any of it is optional. crates/termlens/Cargo.toml:14 asks docs.rs to build with everything on:

[package.metadata.docs.rs]
all-features = true

but nothing tells rustdoc to label what those features gate:

$ grep -rn 'docsrs\|doc(cfg' crates/termlens/src/
$                                    # nothing

So Bitmap, DecodeError, GraphicsPayload::decode and the rest are rendered exactly like Screen::cell — as part of the crate. A reader following the README (cargo add termlens --dev, which does not enable decode) writes payload.decode()?, and finds out from rustc that the method does not exist. The docs gave no warning, and the item they read is on the page they were sent to.

Why it is worth fixing — this crate's documentation is its contract, and the one thing a reader cannot see in it is which half of it they actually installed. decode is off by default deliberately, and the README says to add --features decode "if you test an application that draws inline images" — one sentence, three screens above the API reference where the decision actually bites. The standard remedy exists, is one line of manifest plus one attribute per gated item, and produces the familiar "Available on crate feature decode only" badge that every reader of Rust docs already knows how to read.

Fix — the conventional pattern:

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
// lib.rs, at the top
#![cfg_attr(docsrs, feature(doc_cfg))]

then on each gated item, beside its existing #[cfg(...)]:

#[cfg(feature = "decode")]
#[cfg_attr(docsrs, doc(cfg(feature = "decode")))]
pub fn decode(&self) -> Result<Bitmap, DecodeError> {}

doc_cfg is nightly-only, which is why it is behind the docsrs cfg that only docs.rs sets — stable builds and the MSRV job never see the attribute, and the local cargo doc gates in CONTRIBUTING keep working unchanged. Check the result locally with:

cargo +nightly rustdoc -p termlens --all-features -- --cfg docsrs

Worth doing in the same pass: the insta re-export and assert_screen_snapshot! are gated on the default-on insta feature, so they need the badge too — a consumer who turned default features off is in exactly the same position.

Done when — every #[cfg(feature = …)] public item carries the matching doc(cfg); the manifest passes --cfg docsrs to docs.rs; a nightly cargo rustdoc --cfg docsrs shows the feature badge on Bitmap and on assert_screen_snapshot!; and the stable cargo doc gates in CI are unaffected.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

documentationImprovements or additions to documentationgood first issueGood for newcomershelp wantedExtra attention is needed

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions