2015-02-09 21:24:49 -06:00
|
|
|
|
% Documentation
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Documentation is an important part of any software project, and it's
|
|
|
|
|
first-class in Rust. Let's talk about the tooling Rust gives you to
|
|
|
|
|
document your project.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
## About `rustdoc`
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
The Rust distribution includes a tool, `rustdoc`, that generates documentation.
|
|
|
|
|
`rustdoc` is also used by Cargo through `cargo doc`.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Documentation can be generated in two ways: from source code, and from
|
|
|
|
|
standalone Markdown files.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
## Documenting source code
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
The primary way of documenting a Rust project is through annotating the source
|
|
|
|
|
code. You can use documentation comments for this purpose:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```rust,ignore
|
|
|
|
|
/// Constructs a new `Rc<T>`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::rc::Rc;
|
|
|
|
|
///
|
|
|
|
|
/// let five = Rc::new(5);
|
|
|
|
|
/// ```
|
|
|
|
|
pub fn new(value: T) -> Rc<T> {
|
|
|
|
|
// implementation goes here
|
|
|
|
|
}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
This code generates documentation that looks [like this][rc-new]. I've left the
|
2015-06-22 12:26:51 -05:00
|
|
|
|
implementation out, with a regular comment in its place.
|
|
|
|
|
|
|
|
|
|
The first thing to notice about this annotation is that it uses
|
|
|
|
|
`///` instead of `//`. The triple slash
|
2015-02-19 14:35:26 -06:00
|
|
|
|
indicates a documentation comment.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Documentation comments are written in Markdown.
|
|
|
|
|
|
|
|
|
|
Rust keeps track of these comments, and uses them when generating
|
|
|
|
|
documentation. This is important when documenting things like enums:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// The `Option` type. See [the module level documentation](../) for more.
|
|
|
|
|
enum Option<T> {
|
|
|
|
|
/// No value
|
|
|
|
|
None,
|
|
|
|
|
/// Some value `T`
|
|
|
|
|
Some(T),
|
|
|
|
|
}
|
2015-01-21 13:59:25 -06:00
|
|
|
|
```
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
The above works, but this does not:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```rust,ignore
|
|
|
|
|
/// The `Option` type. See [the module level documentation](../) for more.
|
|
|
|
|
enum Option<T> {
|
|
|
|
|
None, /// No value
|
|
|
|
|
Some(T), /// Some value `T`
|
|
|
|
|
}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
You'll get an error:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```text
|
|
|
|
|
hello.rs:4:1: 4:2 error: expected ident, found `}`
|
|
|
|
|
hello.rs:4 }
|
|
|
|
|
^
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
|
2015-08-21 11:10:46 -05:00
|
|
|
|
correct: documentation comments apply to the thing after them, and there's
|
|
|
|
|
nothing after that last comment.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-08-09 16:15:05 -05:00
|
|
|
|
[rc-new]: https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
### Writing documentation comments
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Anyway, let's cover each part of this comment in detail:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// Constructs a new `Rc<T>`.
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
The first line of a documentation comment should be a short summary of its
|
|
|
|
|
functionality. One sentence. Just the basics. High level.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
///
|
|
|
|
|
/// Other details about constructing `Rc<T>`s, maybe describing complicated
|
|
|
|
|
/// semantics, maybe additional options, all kinds of stuff.
|
|
|
|
|
///
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Our original example had just a summary line, but if we had more things to say,
|
|
|
|
|
we could have added more explanation in a new paragraph.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
#### Special sections
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Next, are special sections. These are indicated with a header, `#`. There
|
2015-06-22 13:22:31 -05:00
|
|
|
|
are four kinds of headers that are commonly used. They aren't special syntax,
|
2015-02-19 14:35:26 -06:00
|
|
|
|
just convention, for now.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// # Panics
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Unrecoverable misuses of a function (i.e. programming errors) in Rust are
|
|
|
|
|
usually indicated by panics, which kill the whole current thread at the very
|
|
|
|
|
least. If your function has a non-trivial contract like this, that is
|
|
|
|
|
detected/enforced by panics, documenting it is very important.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// # Failures
|
|
|
|
|
# fn foo() {}
|
2015-01-21 13:59:25 -06:00
|
|
|
|
```
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
If your function or method returns a `Result<T, E>`, then describing the
|
|
|
|
|
conditions under which it returns `Err(E)` is a nice thing to do. This is
|
|
|
|
|
slightly less important than `Panics`, because failure is encoded into the type
|
|
|
|
|
system, but it's still a good thing to do.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// # Safety
|
|
|
|
|
# fn foo() {}
|
2015-01-21 13:59:25 -06:00
|
|
|
|
```
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
If your function is `unsafe`, you should explain which invariants the caller is
|
|
|
|
|
responsible for upholding.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::rc::Rc;
|
|
|
|
|
///
|
|
|
|
|
/// let five = Rc::new(5);
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-06-22 13:22:31 -05:00
|
|
|
|
Fourth, `Examples`. Include one or more examples of using your function or
|
2015-02-19 14:35:26 -06:00
|
|
|
|
method, and your users will love you for it. These examples go inside of
|
|
|
|
|
code block annotations, which we'll talk about in a moment, and can have
|
|
|
|
|
more than one section:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Simple `&str` patterns:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
|
|
|
|
|
/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// More complex patterns with a lambda:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
|
|
|
|
|
/// assert_eq!(v, vec!["abc", "def", "ghi"]);
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
Let's discuss the details of these code blocks.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
#### Code block annotations
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
To write some Rust code in a comment, use the triple graves:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// ```
|
|
|
|
|
/// println!("Hello, world");
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
If you want something that's not Rust code, you can add an annotation:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// ```c
|
|
|
|
|
/// printf("Hello, world\n");
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
2015-01-21 13:59:25 -06:00
|
|
|
|
```
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
This will highlight according to whatever language you're showing off.
|
|
|
|
|
If you're just showing plain text, choose `text`.
|
|
|
|
|
|
|
|
|
|
It's important to choose the correct annotation here, because `rustdoc` uses it
|
2015-08-20 17:41:24 -05:00
|
|
|
|
in an interesting way: It can be used to actually test your examples in a
|
|
|
|
|
library crate, so that they don't get out of date. If you have some C code but
|
|
|
|
|
`rustdoc` thinks it's Rust because you left off the annotation, `rustdoc` will
|
|
|
|
|
complain when trying to generate the documentation.
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
## Documentation as tests
|
|
|
|
|
|
|
|
|
|
Let's discuss our sample example documentation:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// ```
|
|
|
|
|
/// println!("Hello, world");
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
|
|
|
|
|
automatically add a main() wrapper around your code, and in the right place.
|
|
|
|
|
For example:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-01-21 13:59:25 -06:00
|
|
|
|
/// ```
|
|
|
|
|
/// use std::rc::Rc;
|
|
|
|
|
///
|
|
|
|
|
/// let five = Rc::new(5);
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This will end up testing:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-01-21 13:59:25 -06:00
|
|
|
|
fn main() {
|
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
let five = Rc::new(5);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2015-03-12 15:01:06 -05:00
|
|
|
|
Here's the full algorithm rustdoc uses to postprocess examples:
|
|
|
|
|
|
|
|
|
|
1. Any leading `#![foo]` attributes are left intact as crate attributes.
|
|
|
|
|
2. Some common `allow` attributes are inserted, including
|
|
|
|
|
`unused_variables`, `unused_assignments`, `unused_mut`,
|
|
|
|
|
`unused_attributes`, and `dead_code`. Small examples often trigger
|
|
|
|
|
these lints.
|
|
|
|
|
3. If the example does not contain `extern crate`, then `extern crate
|
|
|
|
|
<mycrate>;` is inserted.
|
|
|
|
|
2. Finally, if the example does not contain `fn main`, the remainder of the
|
|
|
|
|
text is wrapped in `fn main() { your_code }`
|
2015-02-19 14:35:26 -06:00
|
|
|
|
|
|
|
|
|
Sometimes, this isn't enough, though. For example, all of these code samples
|
|
|
|
|
with `///` we've been talking about? The raw text:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
/// Some documentation.
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
looks different than the output:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// Some documentation.
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Yes, that's right: you can add lines that start with `# `, and they will
|
|
|
|
|
be hidden from the output, but will be used when compiling your code. You
|
|
|
|
|
can use this to your advantage. In this case, documentation comments need
|
|
|
|
|
to apply to some kind of function, so if I want to show you just a
|
|
|
|
|
documentation comment, I need to add a little function definition below
|
|
|
|
|
it. At the same time, it's just there to satisfy the compiler, so hiding
|
|
|
|
|
it makes the example more clear. You can use this technique to explain
|
|
|
|
|
longer examples in detail, while still preserving the testability of your
|
|
|
|
|
documentation. For example, this code:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
let x = 5;
|
|
|
|
|
let y = 6;
|
|
|
|
|
println!("{}", x + y);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Here's an explanation, rendered:
|
|
|
|
|
|
|
|
|
|
First, we set `x` to five:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
let x = 5;
|
|
|
|
|
# let y = 6;
|
|
|
|
|
# println!("{}", x + y);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Next, we set `y` to six:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
# let x = 5;
|
|
|
|
|
let y = 6;
|
|
|
|
|
# println!("{}", x + y);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Finally, we print the sum of `x` and `y`:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
# let x = 5;
|
|
|
|
|
# let y = 6;
|
|
|
|
|
println!("{}", x + y);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Here's the same explanation, in raw text:
|
|
|
|
|
|
|
|
|
|
> First, we set `x` to five:
|
2015-03-14 18:09:26 -05:00
|
|
|
|
>
|
2015-02-19 14:35:26 -06:00
|
|
|
|
> ```text
|
|
|
|
|
> let x = 5;
|
|
|
|
|
> # let y = 6;
|
|
|
|
|
> # println!("{}", x + y);
|
|
|
|
|
> ```
|
2015-03-14 18:09:26 -05:00
|
|
|
|
>
|
2015-02-19 14:35:26 -06:00
|
|
|
|
> Next, we set `y` to six:
|
2015-03-14 18:09:26 -05:00
|
|
|
|
>
|
2015-02-19 14:35:26 -06:00
|
|
|
|
> ```text
|
|
|
|
|
> # let x = 5;
|
|
|
|
|
> let y = 6;
|
|
|
|
|
> # println!("{}", x + y);
|
|
|
|
|
> ```
|
2015-03-14 18:09:26 -05:00
|
|
|
|
>
|
2015-02-19 14:35:26 -06:00
|
|
|
|
> Finally, we print the sum of `x` and `y`:
|
2015-03-14 18:09:26 -05:00
|
|
|
|
>
|
2015-02-19 14:35:26 -06:00
|
|
|
|
> ```text
|
|
|
|
|
> # let x = 5;
|
|
|
|
|
> # let y = 6;
|
|
|
|
|
> println!("{}", x + y);
|
|
|
|
|
> ```
|
|
|
|
|
|
|
|
|
|
By repeating all parts of the example, you can ensure that your example still
|
|
|
|
|
compiles, while only showing the parts that are relevant to that part of your
|
|
|
|
|
explanation.
|
|
|
|
|
|
2015-03-22 14:26:23 -05:00
|
|
|
|
### Documenting macros
|
|
|
|
|
|
|
|
|
|
Here’s an example of documenting a macro:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-03-22 14:26:23 -05:00
|
|
|
|
/// Panic with a given message unless an expression evaluates to true.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # #[macro_use] extern crate foo;
|
|
|
|
|
/// # fn main() {
|
|
|
|
|
/// panic_unless!(1 + 1 == 2, “Math is broken.”);
|
|
|
|
|
/// # }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2015-03-26 15:30:33 -05:00
|
|
|
|
/// ```should_panic
|
2015-03-22 14:26:23 -05:00
|
|
|
|
/// # #[macro_use] extern crate foo;
|
|
|
|
|
/// # fn main() {
|
|
|
|
|
/// panic_unless!(true == false, “I’m broken.”);
|
|
|
|
|
/// # }
|
|
|
|
|
/// ```
|
|
|
|
|
#[macro_export]
|
|
|
|
|
macro_rules! panic_unless {
|
|
|
|
|
($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
|
2015-03-23 17:54:39 -05:00
|
|
|
|
}
|
|
|
|
|
# fn main() {}
|
2015-03-22 14:26:23 -05:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
You’ll note three things: we need to add our own `extern crate` line, so that
|
|
|
|
|
we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
|
|
|
|
|
`main()` as well. Finally, a judicious use of `#` to comment out those two
|
|
|
|
|
things, so they don’t show up in the output.
|
|
|
|
|
|
|
|
|
|
### Running documentation tests
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
To run the tests, either
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ rustdoc --test path/to/my/crate/root.rs
|
|
|
|
|
# or
|
|
|
|
|
$ cargo test
|
|
|
|
|
```
|
|
|
|
|
|
2015-08-20 17:41:24 -05:00
|
|
|
|
That's right, `cargo test` tests embedded documentation too. **However,
|
|
|
|
|
`cargo test` will not test binary crates, only library ones.** This is
|
2015-04-16 14:55:10 -05:00
|
|
|
|
due to the way `rustdoc` works: it links against the library to be tested,
|
|
|
|
|
but with a binary, there’s nothing to link to.
|
2015-02-19 14:35:26 -06:00
|
|
|
|
|
|
|
|
|
There are a few more annotations that are useful to help `rustdoc` do the right
|
|
|
|
|
thing when testing your code:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// ```ignore
|
|
|
|
|
/// fn foo() {
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `ignore` directive tells Rust to ignore your code. This is almost never
|
|
|
|
|
what you want, as it's the most generic. Instead, consider annotating it
|
|
|
|
|
with `text` if it's not code, or using `#`s to get a working example that
|
|
|
|
|
only shows the part you care about.
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// ```should_panic
|
|
|
|
|
/// assert!(false);
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`should_panic` tells `rustdoc` that the code should compile correctly, but
|
|
|
|
|
not actually pass as a test.
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// ```no_run
|
|
|
|
|
/// loop {
|
|
|
|
|
/// println!("Hello, world");
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `no_run` attribute will compile your code, but not run it. This is
|
|
|
|
|
important for examples such as "Here's how to start up a network service,"
|
|
|
|
|
which you would want to make sure compile, but might run in an infinite loop!
|
|
|
|
|
|
|
|
|
|
### Documenting modules
|
|
|
|
|
|
|
|
|
|
Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
mod foo {
|
|
|
|
|
//! This is documentation for the `foo` module.
|
|
|
|
|
//!
|
|
|
|
|
//! # Examples
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This is where you'll see `//!` used most often: for module documentation. If
|
|
|
|
|
you have a module in `foo.rs`, you'll often open its code and see this:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
//! A module for using `foo`s.
|
|
|
|
|
//!
|
|
|
|
|
//! The `foo` module contains a lot of useful functionality blah blah blah
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Documentation comment style
|
|
|
|
|
|
|
|
|
|
Check out [RFC 505][rfc505] for full conventions around the style and format of
|
|
|
|
|
documentation.
|
|
|
|
|
|
|
|
|
|
[rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md
|
|
|
|
|
|
|
|
|
|
## Other documentation
|
|
|
|
|
|
|
|
|
|
All of this behavior works in non-Rust source files too. Because comments
|
|
|
|
|
are written in Markdown, they're often `.md` files.
|
|
|
|
|
|
|
|
|
|
When you write documentation in Markdown files, you don't need to prefix
|
|
|
|
|
the documentation with comments. For example:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::rc::Rc;
|
|
|
|
|
///
|
|
|
|
|
/// let five = Rc::new(5);
|
|
|
|
|
/// ```
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
is just
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
~~~markdown
|
|
|
|
|
# Examples
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```
|
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
|
|
let five = Rc::new(5);
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
~~~
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
when it's in a Markdown file. There is one wrinkle though: Markdown files need
|
|
|
|
|
to have a title like this:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```markdown
|
|
|
|
|
% The title
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
This is the example documentation.
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This `%` line needs to be the very first line of the file.
|
|
|
|
|
|
|
|
|
|
## `doc` attributes
|
|
|
|
|
|
|
|
|
|
At a deeper level, documentation comments are sugar for documentation attributes:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
/// this
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
|
|
|
|
|
#[doc="this"]
|
|
|
|
|
# fn bar() {}
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
are the same, as are these:
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-02-19 14:35:26 -06:00
|
|
|
|
//! this
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
#![doc="/// this"]
|
|
|
|
|
```
|
2015-01-21 13:59:25 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
You won't often see this attribute used for writing documentation, but it
|
|
|
|
|
can be useful when changing some options, or when writing a macro.
|
2015-02-09 21:24:49 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
### Re-exports
|
2015-02-09 21:24:49 -06:00
|
|
|
|
|
2015-03-29 05:22:01 -05:00
|
|
|
|
`rustdoc` will show the documentation for a public re-export in both places:
|
2015-02-09 21:24:49 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```ignore
|
2015-02-09 21:24:49 -06:00
|
|
|
|
extern crate foo;
|
|
|
|
|
|
|
|
|
|
pub use foo::bar;
|
|
|
|
|
```
|
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
This will create documentation for bar both inside the documentation for the
|
|
|
|
|
crate `foo`, as well as the documentation for your crate. It will use the same
|
|
|
|
|
documentation in both places.
|
2015-02-09 21:24:49 -06:00
|
|
|
|
|
2015-03-28 10:09:51 -05:00
|
|
|
|
This behavior can be suppressed with `no_inline`:
|
2015-02-09 21:24:49 -06:00
|
|
|
|
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```ignore
|
2015-02-09 21:24:49 -06:00
|
|
|
|
extern crate foo;
|
|
|
|
|
|
|
|
|
|
#[doc(no_inline)]
|
|
|
|
|
pub use foo::bar;
|
|
|
|
|
```
|
2015-02-19 14:35:26 -06:00
|
|
|
|
|
|
|
|
|
### Controlling HTML
|
|
|
|
|
|
|
|
|
|
You can control a few aspects of the HTML that `rustdoc` generates through the
|
|
|
|
|
`#![doc]` version of the attribute:
|
|
|
|
|
|
2015-05-18 13:56:00 -05:00
|
|
|
|
```rust
|
2015-08-09 16:15:05 -05:00
|
|
|
|
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
|
|
|
|
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
|
|
|
|
|
html_root_url = "https://doc.rust-lang.org/")]
|
2015-02-19 14:35:26 -06:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This sets a few different options, with a logo, favicon, and a root URL.
|
|
|
|
|
|
|
|
|
|
## Generation options
|
|
|
|
|
|
2015-04-25 09:46:34 -05:00
|
|
|
|
`rustdoc` also contains a few other options on the command line, for further customization:
|
2015-02-19 14:35:26 -06:00
|
|
|
|
|
|
|
|
|
- `--html-in-header FILE`: includes the contents of FILE at the end of the
|
|
|
|
|
`<head>...</head>` section.
|
|
|
|
|
- `--html-before-content FILE`: includes the contents of FILE directly after
|
|
|
|
|
`<body>`, before the rendered content (including the search bar).
|
|
|
|
|
- `--html-after-content FILE`: includes the contents of FILE after all the rendered content.
|
2015-04-16 14:43:56 -05:00
|
|
|
|
|
|
|
|
|
## Security note
|
|
|
|
|
|
|
|
|
|
The Markdown in documentation comments is placed without processing into
|
|
|
|
|
the final webpage. Be careful with literal HTML:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
/// <script>alert(document.cookie)</script>
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|