Skip to content

Commit

Permalink
Auto merge of #75778 - AndyGauge:75521-rustdoc-book-improvements, r=j…
Browse files Browse the repository at this point in the history
…yn514

75521 rustdoc book improvements

Added some guidelines about documenting with rustdoc
Fixes #75521
  • Loading branch information
bors committed Nov 6, 2020
2 parents 7e9a36f + 881820a commit a601302
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 31 deletions.
2 changes: 2 additions & 0 deletions src/doc/rustdoc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- [What is rustdoc?](what-is-rustdoc.md)
- [How to write documentation](how-to-write-documentation.md)
- [What to include (and exclude)](what-to-include.md)
- [Command-line arguments](command-line-arguments.md)
- [The `#[doc]` attribute](the-doc-attribute.md)
- [Documentation tests](documentation-tests.md)
Expand All @@ -10,3 +11,4 @@
- [Passes](passes.md)
- [Advanced features](advanced-features.md)
- [Unstable features](unstable-features.md)
- [References](references.md)
120 changes: 105 additions & 15 deletions src/doc/rustdoc/src/how-to-write-documentation.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,85 @@
# How to write documentation

Good documentation is not natural. There are opposing goals that make writing
good documentation difficult. It requires expertise in the subject but also
writing to a novice perspective. Documentation therefore often glazes over
implementation detail, or leaves readers with unanswered questions.

There are a few tenets to Rust documentation that can help guide anyone through
the process of documenting libraries so that everyone has an ample opportunity
to use the code.

This chapter covers not only how to write documentation but specifically
how to write **good** documentation. Something to keep in mind when
writing documentation is that your audience is not just yourself but others
who simply don't have the context you do. It is important to be as clear
how to write **good** documentation. It is important to be as clear
as you can, and as complete as possible. As a rule of thumb: the more
documentation you write for your crate the better. If an item is public
then it should be documented.

## Basic structure
## Getting Started

Documenting a crate should begin with front-page documentation. As an
example, the [`hashbrown`] crate level documentation summarizes the role of
the crate, provides links to explain technical details, and explains why you
would want to use the crate.

After introducing the crate, it is important that the front-page gives
an example of how to use the crate in a real world setting. Stick to the
library's role in the example, but do so without shortcuts to benefit users who
may copy and paste the example to get started.

[`futures`] uses inline comments to explain line by line
the complexities of using a [`Future`], because a person's first exposure to
rust's [`Future`] may be this example.

The [`backtrace`] documentation walks through the whole process, explaining
changes made to the `Cargo.toml` file, passing command line arguments to the
compiler, and shows a quick example of backtrace in the wild.

Finally, the front-page can eventually become a comprehensive reference
how to use a crate, like [`regex`]. In this front page, all
requirements are outlined, the edge cases shown, and practical examples
provided. The front page goes on to show how to use regular expressions
then concludes with crate features.

Don't worry about comparing your crate, which is just beginning, to other more
developed crates. To get the documentation to something more polished, start
incrementally and put in an introduction, example, and features. Rome was not
built in a day!

The first lines within the `lib.rs` will compose the front-page, and they
use a different convention than the rest of the rustdocs. Lines should
start with `//!` which indicate module-level or crate-level documentation.
Here's a quick example of the difference:

```rust,ignore
//! Fast and easy queue abstraction.
//!
//! Provides an abstraction over a queue. When the abstraction is used
//! there are these advantages:
//! - Fast
//! - [`Easy`]
//!
//! [`Easy`]: http://thatwaseasy.example.com
/// This module makes it easy.
pub mod easy {
/// Use the abstract function to do this specific thing.
pub fn abstract() {}
}
```

Ideally, this first line of documentation is a sentence without highly
technical details, but with a good description of where this crate fits
within the rust ecosystem. Users should know whether this crate meets their use
case after reading this line.

## Documenting components

Whether it is modules, structs, functions, or macros: the public
API of all code should have documentation. Rarely does anyone
complain about too much documentation!

It is recommended that each item's documentation follows this basic structure:

Expand All @@ -23,9 +94,9 @@ It is recommended that each item's documentation follows this basic structure:
```

This basic structure should be straightforward to follow when writing your
documentation and, while you might think that a code example is trivial,
the examples are really important because they can help your users to
understand what an item is, how it is used, and for what purpose it exists.
documentation; while you might think that a code example is trivial,
the examples are really important because they can help users understand
what an item is, how it is used, and for what purpose it exists.

Let's see an example coming from the [standard library] by taking a look at the
[`std::env::args()`][env::args] function:
Expand Down Expand Up @@ -62,21 +133,40 @@ for argument in env::args() {
[`args_os`]: ./fn.args_os.html
``````

Everything before the first empty line will be reused to describe the component
in searches and module overviews. For example, the function `std::env::args()`
above will be shown on the [`std::env`] module documentation. It is good
practice to keep the summary to one line: concise writing is a goal of good
documentation.

Because the type system does a good job of defining what types a function
passes and returns, there is no benefit of explicitly writing it
into the documentation, especially since `rustdoc` adds hyper links to all types in the function signature.

In the example above, a 'Panics' section explains when the code might abruptly exit,
which can help the reader prevent reaching a panic. A panic section is recommended
every time edge cases in your code can be reached if known.

As you can see, it follows the structure detailed above: it starts with a short
sentence explaining what the functions does, then it provides more information
and finally provides a code example.

## Markdown

`rustdoc` is using the [commonmark markdown specification]. You might be
`rustdoc` uses the [commonmark markdown specification]. You might be
interested into taking a look at their website to see what's possible to do.
- [commonmark quick reference]
- [current spec]

## Lints

To be sure that you didn't miss any item without documentation or code examples,
you can take a look at the rustdoc lints [here][rustdoc-lints].

[standard library]: https://doc.rust-lang.org/stable/std/index.html
[env::args]: https://doc.rust-lang.org/stable/std/env/fn.args.html
[`backtrace`]: https://docs.rs/backtrace/0.3.50/backtrace/
[commonmark markdown specification]: https://commonmark.org/
[rustdoc-lints]: lints.md
[commonmark quick reference]: https://commonmark.org/help/
[env::args]: https://doc.rust-lang.org/stable/std/env/fn.args.html
[`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html
[`futures`]: https://docs.rs/futures/0.3.5/futures/
[`hashbrown`]: https://docs.rs/hashbrown/0.8.2/hashbrown/
[`regex`]: https://docs.rs/regex/1.3.9/regex/
[standard library]: https://doc.rust-lang.org/stable/std/index.html
[current spec]: https://spec.commonmark.org/current/
[`std::env`]: https://doc.rust-lang.org/stable/std/env/index.html#functions
31 changes: 31 additions & 0 deletions src/doc/rustdoc/src/references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# References

There are many great `rustdoc` references out there.
If you know of other great resources, please submit a pull request!

## Official

- [Learn Rust]
- [Rust By Example]
- [Rust Reference]
- [RFC 1574: More API Documentation Conventions]
- [RFC 1946: Intra Rustdoc Links]

## Community
- [API Guidelines]
- [Github tagged RFCs]
- [Github tagged issues]
- [RFC (stalled) front page styleguide]
- [Guide on how to write documenation for a Rust crate]


[API Guidelines]: https://rust-lang.github.io/api-guidelines/documentation.html
[Github tagged RFCs]: https://github.com/rust-lang/rfcs/issues?q=label%3AT-rustdoc
[Github tagged issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AT-rustdoc
[Guide on how to write documenation for a Rust crate]: https://blog.guillaume-gomez.fr/articles/2020-03-12+Guide+on+how+to+write+documentation+for+a+Rust+crate
[Learn Rust]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments
[RFC 1574: More API Documentation Conventions]: https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html
[RFC 1946: Intra Rustdoc Links]: https://rust-lang.github.io/rfcs/1946-intra-rustdoc-links.html
[RFC (stalled) front page styleguide]: https://github.com/rust-lang/rfcs/pull/1687
[Rust By Example]: https://doc.rust-lang.org/stable/rust-by-example/meta/doc.html
[Rust Reference]: https://doc.rust-lang.org/stable/reference/comments.html#doc-comments
35 changes: 19 additions & 16 deletions src/doc/rustdoc/src/what-is-rustdoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ CSS, and JavaScript.

## Basic usage

Let's give it a try! Let's create a new project with Cargo:
Let's give it a try! Create a new project with Cargo:

```bash
$ cargo new docs
$ cd docs
```

In `src/lib.rs`, you'll find that Cargo has generated some sample code. Delete
In `src/lib.rs`, Cargo has generated some sample code. Delete
it and replace it with this:

```rust
Expand All @@ -31,8 +31,12 @@ $ rustdoc src/lib.rs

This will create a new directory, `doc`, with a website inside! In our case,
the main page is located in `doc/lib/index.html`. If you open that up in
a web browser, you'll see a page with a search bar, and "Crate lib" at the
top, with no contents. There's two problems with this: first, why does it
a web browser, you will see a page with a search bar, and "Crate lib" at the
top, with no contents.

## Configuring rustdoc

There are two problems with this: first, why does it
think that our package is named "lib"? Second, why does it not have any
contents?

Expand All @@ -46,7 +50,7 @@ $ rustdoc src/lib.rs --crate-name docs

Now, `doc/docs/index.html` will be generated, and the page says "Crate docs."

For the second issue, it's because our function `foo` is not public; `rustdoc`
For the second issue, it is because our function `foo` is not public; `rustdoc`
defaults to generating documentation for only public functions. If we change
our code...

Expand All @@ -61,7 +65,7 @@ pub fn foo() {}
$ rustdoc src/lib.rs --crate-name docs
```

We'll have some generated documentation. Open up `doc/docs/index.html` and
We now have some generated documentation. Open up `doc/docs/index.html` and
check it out! It should show a link to the `foo` function's page, which
is located at `doc/docs/fn.foo.html`. On that page, you'll see the "foo is
a function" we put inside the documentation comment in our crate.
Expand All @@ -85,13 +89,12 @@ dependency=<path>/docs/target/debug/deps
You can see this with `cargo doc --verbose`.

It generates the correct `--crate-name` for us, as well as pointing to
`src/lib.rs` But what about those other arguments? `-o` controls the
*o*utput of our docs. Instead of a top-level `doc` directory, you'll
notice that Cargo puts generated documentation under `target`. That's
the idiomatic place for generated files in Cargo projects. Also, it
passes `-L`, a flag that helps rustdoc find the dependencies
your code relies on. If our project used dependencies, we'd get
documentation for them as well!
`src/lib.rs`. But what about those other arguments?
- `-o` controls the *o*utput of our docs. Instead of a top-level
`doc` directory, notice that Cargo puts generated documentation under
`target`. That is the idiomatic place for generated files in Cargo projects.
- `-L` flag helps rustdoc find the dependencies your code relies on.
If our project used dependencies, we would get documentation for them as well!

## Outer and inner documentation

Expand All @@ -118,7 +121,7 @@ For more information about the `//!` syntax, see [the Book].

## Using standalone Markdown files

`rustdoc` can also generate HTML from standalone Markdown files. Let's
`rustdoc` can also generate HTML from standalone Markdown files. Let' s
give it a try: create a `README.md` file with these contents:

````text
Expand All @@ -128,7 +131,7 @@ This is a project to test out `rustdoc`.
[Here is a link!](https://www.rust-lang.org)
## Subheading
## Example
```rust
fn foo() -> i32 {
Expand All @@ -143,7 +146,7 @@ And call `rustdoc` on it:
$ rustdoc README.md
```

You'll find an HTML file in `docs/doc/README.html` generated from its
You will find an HTML file in `docs/doc/README.html` generated from its
Markdown contents.

Cargo currently does not understand standalone Markdown files, unfortunately.
Expand Down
Loading

0 comments on commit a601302

Please sign in to comment.