-
Notifications
You must be signed in to change notification settings - Fork 1.6k
RFC: Cargo feature descriptions #3485
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
base: master
Are you sure you want to change the base?
Changes from 4 commits
7aa7df0
c52bd96
51400c5
129ab25
326b4d9
6a793f5
4957dd0
9cc3334
9d87695
b6d13a6
c330adb
b2b27a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
- Feature Name: feature-documentation | ||
- Start Date: 2023-09-09 | ||
- RFC PR: [rust-lang/rfcs#3485](https://github.com/rust-lang/rfcs/pull/3485) | ||
- Rust Issue: | ||
[rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||
|
||
# Summary | ||
|
||
[summary]: #summary | ||
|
||
This RFC describes a new key to under `features` in `Cargo.toml` for | ||
tgross35 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
documentation. This will allow Cargo to display this information to the user and | ||
provide a way for `rustdoc` to eventually render this data (how this is rendered | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One of the issues is how rustdoc consumes the data. rust doc generally knows nothing about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did bring it up when I initially proposed this feature, https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/Descriptions.20for.20feature.20flags and then opened a draft RFC suggesting that |
||
is outside the scope of this RFC). | ||
|
||
Please see the parent meta RFC for background information: [`feature-metadata`]. | ||
joshtriplett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Motivation | ||
|
||
[motivation]: #motivation | ||
|
||
Cargo features have become extremely widely used, with many crates having at | ||
least some level of configuration and larger crates winding up with tens of | ||
gates. Desipte being a first class component of crate structure, they suffer | ||
tgross35 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
from a documentation problem: users need to maintain documentation separate from | ||
feature definition, typically a manually-created table within API docs. | ||
|
||
This RFC proposes adding feature documentation to `Cargo.toml`, which will allow | ||
for keeping feature definitions and documentation together. | ||
|
||
# Guide-level explanation | ||
|
||
[guide-level-explanation]: #guide-level-explanation | ||
|
||
A new `doc` key will be allowed within a feature's table. This key provides a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naming (not finding the past discussion on it)
We also tend to not use abbreviations as much. For example, for public-private dependencies, we discussed using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epage In my opinion, I think this should be I think we should encourage using this not just for a "description" of a feature but for "documentation" for a feature, and that's supported by the idea of it showing up in rustdoc and allowing markdown. And I think there's a big difference in length between It's hard enough to get people to write documentation; let's not have any extra friction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Personally, I'd prefer we be consistent and not just focusing on character count.
We've shot well past that by requiring a "long form" just to write documentation, hurting both discoverability, character count, and ease of not typing some of those characters on international keyboards. |
||
markdown docstring describing the feature. Like with `#[doc(...)]`, the first | ||
line will be treated as a summary. | ||
tgross35 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```toml | ||
[features] | ||
# Feature without documentation | ||
foo = [] | ||
|
||
# Short documentation comment | ||
bar = { enables = ["foo"], doc = "simple docstring here"} | ||
|
||
# Tables are preferred for longer descriptions | ||
[features.corge] | ||
enables = ["bar", "baz"] | ||
doc = """ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another good question raised was "should we also support intra-doc links in this documentation?". I personally think we should and make the context the same as the crate top-level. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see you mentioned it below, my bad. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the response! The follow-up question from me would be: Is there any compatibility issues if we hadn't implemented this RFC and rustdoc change all together? If not then this RFC can safely go first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure. From cargo perspective, whether there are intra-doc links or not in this documentation doesn't matter. But it'll definitely need to be mentioned when support will be discussed in rustdoc. For the current case, I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good to me. @tgross35 could you add something like this? (or whichever way you'd like to rephase this) - Rustdoc can build on this to show feature documentation.
+ Rustdoc can build on this to show feature documentation.
+ If this RFC gets stabilized before any corresponding change in rustdoc,
+ its documentation should highlight that rustdoc may parse the description and support intra-doc links in the feature.
+ Users need to be aware of this potential incompatibility. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added, thank you! |
||
# corge | ||
|
||
tgross35 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This could be a longer description of this feature | ||
""" | ||
``` | ||
|
||
See [`feature-metadata`] for information about `enables`. | ||
|
||
# Reference-level explanation | ||
|
||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
The new `doc` key accepts markdown-flavored text, and should be thought of as | ||
the equivalent to a `#[doc(...)]` attribute. Like doc comments, the first line | ||
should be treated as a summary. Intra-doc link support is not included in this | ||
RFC, so they should not be used. | ||
|
||
There is nothing in this RFC that cargo **must** do with this action, since it is | ||
mainly intended for the consumption of `rustdoc` or `docs.rs`. However, it can | ||
be used for general diagnostic information such as during `cargo add` or a | ||
possible `cargo info` command. A sample application with `cargo add`: | ||
|
||
```text | ||
crab@rust foobar % cargo add regex | ||
Updating crates.io index | ||
Adding regex v1.7.3 to dependencies. | ||
Features: | ||
+ perf Enables all performance related features | ||
+ perf-dfa Enables the use of a lazy DFA for matching | ||
+ perf-inline Enables the use of aggressive inlining inside | ||
match routines | ||
+ perf-literal Enables the use of literal optimizations for | ||
speeding up matches | ||
+ std When enabled, this will cause regex to use the | ||
standard library | ||
+ unicode Enables all Unicode features | ||
|
||
Updating crates.io index | ||
``` | ||
|
||
*(features like `aho-corasick`, `memchr`, or `use_std` would likely be | ||
`public = false` since they aren't listed on the crate landing page)* | ||
|
||
Any tools that want the information in `doc` will require access to the | ||
manifest. Adding this information to the index was decided against due to | ||
concerns about bloat, but this is further discussed in | ||
[future possibilities][future-possibilities]. | ||
|
||
# Drawbacks | ||
|
||
[drawbacks]: #drawbacks | ||
|
||
- Added complexity to Cargo. | ||
- Exact implementation details do add test surface area | ||
- A markdown parser is required to properly parse the `doc` field. | ||
- Docstrings can be lengthy, adding noise to `Cargo.toml`. This could | ||
potentially be solved with the below mentioned `doc-file` key. | ||
- When rendering features in documentation, this RFC does not specify any way | ||
for `rustdoc` to get the information it requires. This will require separate | ||
design work. | ||
- Unlike with the [`document-features`](https://crates.io/crates/document-features) | ||
crate there is no way to group features in into sections or have a | ||
tgross35 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
user-specified layout | ||
- Users cannot control features ordering in documentation since the TOML specification defines table keys as unordered. | ||
|
||
# Rationale and alternatives | ||
|
||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
- To avoid increasing the size of the registry index, this does not add `doc` | ||
to a package's index entry. This means a `.crate` file must be downloaded | ||
and extracted to access the features. | ||
- Feature descriptions could be specified somewhere in Rust source files. This | ||
has the downside of creating multiple sources of truth on features. | ||
- Cargo could parse doc comments in `Cargo.toml`, like the `document-features` | ||
crate (linked below). | ||
|
||
```toml | ||
# RFC proposal | ||
foo = { enables = [], doc = "foo feature" } | ||
|
||
# Alternative equivalent using doc comments | ||
## foo feature | ||
foo = [] | ||
``` | ||
|
||
This was decided against as part of this RFC because it would mean that | ||
TOML-compliant parsers (including anything `serde`-based) would be | ||
insufficient to extract all information in the manifest, requiring custom | ||
deserialization of the fields via a format-preserving parser. This differs | ||
from documentation in Rust source as the doc-comment behavior is described | ||
specified within the grammar with parsers supporting extracting those | ||
elements. | ||
|
||
# Prior art | ||
|
||
[prior-art]: #prior-art | ||
|
||
- There is an existing crate that uses TOML comments to create a features table: | ||
<https://docs.rs/document-features/latest/document_features/> | ||
- `docs.rs` displays a feature table, but it is fairly limited. If features | ||
start with `_`, they are hidden from this table ([example](https://docs.rs/crate/regex/latest/features)). | ||
- `lib.rs` extracts feature documentation from `Cargo.toml` and source ([example](https://lib.rs/crates/regex/features)) | ||
|
||
# Unresolved questions | ||
|
||
[unresolved-questions]: #unresolved-questions | ||
|
||
- Rather than being consistent with `rustdoc` and accepting markdown, should the | ||
`doc` key be consistent with `package.description` and only support plain | ||
Comment on lines
+173
to
+174
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wanted to highlight this for discussion. My main interest is in being able to show summaries in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Package descriptions tend to use markdown Markdown's goal is to look fine even when displayed as plain text. You could define it as the first line being for CLI help, and the rest for docs. Analogous to how rustdoc handles doc comments. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kornelski 👍 for using markdown. And I think it makes sense to treat the first logical line (anything before the first double-newline) as a "short description", cutting off subsequent paragraphs in places where full documentation doesn't fit. |
||
text? This needs to be a point of discussion before approval of this RFC. | ||
|
||
# Future possibilities | ||
|
||
[future-possibilities]: #future-possibilities | ||
|
||
- Rustdoc can build on this to show feature documentation. | ||
- At some point, the decision to not include `doc` in the index could be | ||
reevaluated. Including only the first (summary) line of `doc` could be a | ||
possibility. | ||
- `cargo add` can show the `doc` and `deprecated` summary with the listed | ||
features. | ||
- [`cargo-info`] can use this information to provide feature descriptions. | ||
- crates-io could be updated to render feature documentation | ||
- Feature documentation could be allowed in a separate markdown file. For | ||
convenience, markdown anchors could be used to specify a section, so multiple | ||
features can share the same file. This could be a good option for features | ||
requiring long descriptions. | ||
|
||
```toml | ||
foo = { enables = [], doc-file = "features.md#foo" } | ||
bar = { enables = [], doc-file = "features.md#bar" } | ||
``` | ||
|
||
[cargo #12335]: https://github.com/rust-lang/cargo/issues/12235 | ||
[cargo #10882]: https://github.com/rust-lang/cargo/issues/10882 | ||
[`cargo-info`]: https://github.com/rust-lang/cargo/issues/948 | ||
[`deprecated`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute | ||
[`deprecated-suggestions`]: https://github.com/rust-lang/rust/issues/94785 | ||
[discussion on since]: https://github.com/rust-lang/rfcs/pull/3416#discussion_r1172895497 | ||
[`public_private_dependencies`]: https://rust-lang.github.io/rfcs/1977-public-private-dependencies.html | ||
[`rustdoc-cargo-configuration`]: https://github.com/rust-lang/rfcs/pull/3421 | ||
[`tokio`]: https://docs.rs/crate/tokio/latest/features | ||
[visibility attribute]: https://ant.apache.org/ivy/history/latest-milestone/ivyfile/conf.html | ||
[`feature-metadata`]: https://github.com/rust-lang/rfcs/pull/3416 |
Uh oh!
There was an error while loading. Please reload this page.