-
Notifications
You must be signed in to change notification settings - Fork 36
Add guidelines about writing documentation #35
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
Changes from all commits
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,149 @@ | ||||||||||||||
# How to write documentation | ||||||||||||||
|
||||||||||||||
This document explains how to write documentation for the std/core public APIs. | ||||||||||||||
|
||||||||||||||
Let's start with some general information: | ||||||||||||||
|
||||||||||||||
### Contractions | ||||||||||||||
|
||||||||||||||
It is common in English to have contractions such as "don't" or "can't". Do not | ||||||||||||||
use these in documentation. Always write their "full form": | ||||||||||||||
|
||||||||||||||
* "do not" instead of "don't" | ||||||||||||||
* "cannot" instead of "can't" | ||||||||||||||
* "it would" instead of "it'd" | ||||||||||||||
* "it will" instead of "it'll" | ||||||||||||||
* "it is"/"it has" instead of "it's" | ||||||||||||||
* "you are" instead of "you're" | ||||||||||||||
* "they are" instead of "they're" | ||||||||||||||
* etc | ||||||||||||||
|
||||||||||||||
The only exception to this rule is "let's" as it is specific/known/common enough. | ||||||||||||||
|
||||||||||||||
The reason is simply to make the reading simpler for as many people as possible. | ||||||||||||||
|
||||||||||||||
### When to use inline code blocks | ||||||||||||||
|
||||||||||||||
Whenever you are talking about a type or anything code related, it should be in a | ||||||||||||||
inline code block. As a reminder, a inline code block is created with backticks | ||||||||||||||
(\`). For example: | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
```text | ||||||||||||||
This a `Vec` and it has a method `push` which you can call by doing `Vec::push`. | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### When to use intra-doc links | ||||||||||||||
|
||||||||||||||
Intra-doc links (you can see the full explanations for the feature | ||||||||||||||
[here](https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html)) | ||||||||||||||
should be used as much as possible whenever a type is mentioned. | ||||||||||||||
|
||||||||||||||
Little note: when you are documenting an item, no need to link to it. So if you | ||||||||||||||
write documentation for `String::push_str` method, no need to link to the method | ||||||||||||||
`push_str` or to the `String` type. | ||||||||||||||
Comment on lines
+42
to
+44
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. This paragraph seems to be missing a few words.
Suggested change
|
||||||||||||||
|
||||||||||||||
If you have cases like `Vec<String>`, you need to use intra-doc links on both | ||||||||||||||
`Vec` and `String` as well. It would look like this: | ||||||||||||||
|
||||||||||||||
```text | ||||||||||||||
This is a [`Vec`]`<`[`String`]`>`. | ||||||||||||||
``` | ||||||||||||||
Comment on lines
+46
to
+51
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. This is something we currently rarely do, and I'm not sure we should do that everywhere, as it's quite tedious with not a lot of benefit. 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. It makes the reading better. As such, I think it's a good enough reason. (It's also something we enforced when the documentation team still existed too) 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.
It don't think it does. It just adds more noise with the changes in color/formatting. If both Regardless, this is guideline is not uncontroversial. It's fine to document and merge guidelines in to std-dev-guide that we already follow, by documenting existing practice. But new rules that we don't currently follow should first have some discussion and a decision. Right now, we have exactly one doc comment that uses the syntax 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. You're absolutely right. I remembered that we had a lot more around. I guess my memory about it is completely outdated... I still appreciate to be able to click on each type separately but maybe it's only me... |
||||||||||||||
|
||||||||||||||
Extra explanations: since both `Vec` and `String` are in codeblocks, `<` and `>` | ||||||||||||||
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. "explanation" is usually used a an uncountable noun, with no separate plural form:
Suggested change
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. TIL, thanks! 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. Wikipedia seems to say it's countable: https://simple.wiktionary.org/wiki/explanation whereas oxford dictionary says it's both: https://www.oxfordlearnersdictionaries.com/definition/english/explanation 😆 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. It can be countable, however that usually applies to when, e.g. you're doing multiple explanations to different people or at different times. If it's being explained in one place, that's a single explanation even if it has multiple parts. (this is similar to how "fish" is uncountable except when talking about different kinds of fish) 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. Tricky language. Thanks for the explanation! |
||||||||||||||
should as well, otherwise it would render badly. | ||||||||||||||
|
||||||||||||||
### Code blocks | ||||||||||||||
|
||||||||||||||
With rustdoc, code blocks are tested (because they are treated as Rust code | ||||||||||||||
blocks by default). It allows us to know if the documentation is up to date. As | ||||||||||||||
such, please avoid using `ignore` as much as possible on code blocks! If you | ||||||||||||||
want as a language other than Rust, simply set it in the code block tags: | ||||||||||||||
|
||||||||||||||
```text | ||||||||||||||
This is not rust code! | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
Some special cases: | ||||||||||||||
* If the code example cannot be run (when documenting a I/O item for example), | ||||||||||||||
use `no_run`. | ||||||||||||||
* If it is expected to fail, use `should_panic`. | ||||||||||||||
* If it is expected to fail compilation (which be quite rare!), use `compile_fail`. | ||||||||||||||
|
||||||||||||||
You can find more information about code blocks | ||||||||||||||
[here](https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html). | ||||||||||||||
|
||||||||||||||
## How to write documentation for a module | ||||||||||||||
|
||||||||||||||
A module is supposed to contain "similar" items. As such, its documentation is | ||||||||||||||
supposed to give an overview and eventually **a base** to understand what the | ||||||||||||||
items it contains are doing. | ||||||||||||||
|
||||||||||||||
You can take a look at the | ||||||||||||||
[f32 module](https://doc.rust-lang.org/nightly/std/f32/index.html) or at the | ||||||||||||||
[fmt module](https://doc.rust-lang.org/nightly/std/fmt/index.html) to see | ||||||||||||||
good examples. | ||||||||||||||
|
||||||||||||||
## How to write documentation for functions/methods | ||||||||||||||
|
||||||||||||||
The basic format of each documented methods/functions should roughly look like this: | ||||||||||||||
|
||||||||||||||
```text | ||||||||||||||
[explanations] | ||||||||||||||
|
||||||||||||||
[example(s)] | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### Explanations | ||||||||||||||
|
||||||||||||||
By `explanations` we mean that the text should explain what the method and what | ||||||||||||||
each of its arguments are for. Let's take this method for example: | ||||||||||||||
|
||||||||||||||
```rust | ||||||||||||||
pub fn concat_str(&self, s: &str) -> String { | ||||||||||||||
if s.is_empty() { | ||||||||||||||
panic!("empty concat string"); | ||||||||||||||
} | ||||||||||||||
format!("{}{}", self.string, s) | ||||||||||||||
} | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
The explanation should look like this: | ||||||||||||||
|
||||||||||||||
```text | ||||||||||||||
Returns a new [`String`] which contains `&self` content with `s` added at the end. | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### Panic? | ||||||||||||||
|
||||||||||||||
If the function/method can panic in certain circumstances, it must to be | ||||||||||||||
mentioned! This explanation needs to be prepended by a `Panics` title: | ||||||||||||||
|
||||||||||||||
```text | ||||||||||||||
# Panics | ||||||||||||||
|
||||||||||||||
`concat_str` panics if `s` is empty. | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### Examples | ||||||||||||||
|
||||||||||||||
As for the examples, they have to show the usage of the function/method. Just | ||||||||||||||
like the `panic` section, they need to be prepended by a `Examples` title. | ||||||||||||||
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. In many cases we just have 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 don't remember the debate behind this (I think @Manishearth was involved in this debate? Please correct me if I'm wrong!) but it's what we already recommend in the rustdoc book. I'm fine with updating both though if needed. 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 don't remember being involved in this debate at all. I think both are fine. I recall making sure the clippy lint for this can detect both (or at least talking about that). 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. Then it was maybe at the time when the documentation team still existed I guess... Like said above, I'm fine with both. |
||||||||||||||
|
||||||||||||||
It is better if you use `assert*!` macros at the end to ensure that the example | ||||||||||||||
is working as expected. It also allows the readers to understand more easily | ||||||||||||||
what the function is doing (or returning). | ||||||||||||||
|
||||||||||||||
# Examples | ||||||||||||||
|
||||||||||||||
``` | ||||||||||||||
let s = MyType::new("hello "); | ||||||||||||||
assert_eq!("hello Georges", s.concat_str("Georges").as_str()); | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
## How to write documentation for other items | ||||||||||||||
|
||||||||||||||
It is mostly the same as for methods and functions except that the examples | ||||||||||||||
are (strongly) recommended and not mandatory. | ||||||||||||||
|
||||||||||||||
A good example often shows how to create the item. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Reviewing doc changes | ||
|
||
Most of the time, it is mostly reviewing that the documentation isn't wrong | ||
in any way and that it follows the | ||
[how to write documentation](./how-to-write-documentation.md) guideline. | ||
|
||
There is however something where we need to be extra careful: stability | ||
guarantees. | ||
|
||
## Stability guarantees | ||
|
||
First, short explanation about what a stability guarantee is: a statement in | ||
the document which explains what the item is doing in a precise case. For | ||
GuillaumeGomez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
example: | ||
|
||
* Showing precisely how a function on floats handles `NaN`. | ||
* Saying that a sort method has a particular running-time bound. | ||
|
||
So if a doc change updates/adds/removes a stability guarantee, it has to be | ||
GuillaumeGomez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
**very** carefully handled and needs to go through the | ||
[libs API team FCP](https://rustc-dev-guide.rust-lang.org/stabilization_guide.html?highlight=fcp#fcp). | ||
|
||
It can be circumvented by adding a `# Current Implementation` section | ||
[like done here](https://github.com/rust-lang/rust/blob/4a8d2e3856c0c75c71998b6c85937203839b946d/library/alloc/src/slice.rs#L250). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
- [doc alias policy](./doc-alias-policy.md) | ||
- [safety comments policy](./safety-comments.md) | ||
- [how to write documentation](./how-to-write-documentation.md) | ||
- [reviewing doc changes](./reviewing-doc-changes.md) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? We currently have over 600 of such contractions in doc comments in
library/*
.I think it's definitely good to have guidelines, but we should probably start with writing down the existing practices rather than making new rules that we currently don't follow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the explanations I provided below provide explanations for it. Making documentation easier to read by reducing congestion like trying to figure out if
'd
is "had" or "should/would" doesn't seem like a bad idea. Until now we didn't have a guideline so it was to be expected. I don't see why it'd be an issue when writing new documentation though. Nothing prevents us to slowly update the existing documentation.But maybe you had some other reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll point out: while there is no such thing as "standardized" english, only some of these contractions are found in formal usage (don't, can't, it'll, it's, you're, they're are found, whereas 'd for should/would/had is not as much), and I cannot think of a single English contraction that is ambiguous in formal usage (e.g. your example about
'd
doesn't apply at all). Folks are more loose in chats/etc, but most modern English style guides allow contractions, and if anything it reads weirdly if you omit them. Discouraging contractions seems rather weird.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I followed what the rustc errors do (which disallow contractions). Maybe I'm once again imagining things...