3 Documentation is an important part of any software project, and it's
4 first-class in Rust. Let's talk about the tooling Rust gives you to
9 The Rust distribution includes a tool, `rustdoc`, that generates documentation.
10 `rustdoc` is also used by Cargo through `cargo doc`.
12 Documentation can be generated in two ways: from source code, and from
13 standalone Markdown files.
15 ## Documenting source code
17 The primary way of documenting a Rust project is through annotating the source
18 code. You can use documentation comments for this purpose:
21 /// Constructs a new `Rc<T>`.
28 /// let five = Rc::new(5);
30 pub fn new(value: T) -> Rc<T> {
31 // implementation goes here
35 This code generates documentation that looks [like this][rc-new]. I've left the
36 implementation out, with a regular comment in its place. That's the first thing
37 to notice about this annotation: it uses `///`, instead of `//`. The triple slash
38 indicates a documentation comment.
40 Documentation comments are written in Markdown.
42 Rust keeps track of these comments, and uses them when generating
43 documentation. This is important when documenting things like enums:
46 /// The `Option` type. See [the module level documentation](../) for more.
55 The above works, but this does not:
58 /// The `Option` type. See [the module level documentation](../) for more.
61 Some(T), /// Some value `T`
68 hello.rs:4:1: 4:2 error: expected ident, found `}`
73 This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
74 correct: documentation comments apply to the thing after them, and there's no
75 thing after that last comment.
77 [rc-new]: http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new
79 ### Writing documentation comments
81 Anyway, let's cover each part of this comment in detail:
84 /// Constructs a new `Rc<T>`.
88 The first line of a documentation comment should be a short summary of its
89 functionality. One sentence. Just the basics. High level.
93 /// Other details about constructing `Rc<T>`s, maybe describing complicated
94 /// semantics, maybe additional options, all kinds of stuff.
99 Our original example had just a summary line, but if we had more things to say,
100 we could have added more explanation in a new paragraph.
102 #### Special sections
104 Next, are special sections. These are indicated with a header, `#`. There
105 are four kinds of headers that are commonly used. They aren't special syntax,
106 just convention, for now.
113 Unrecoverable misuses of a function (i.e. programming errors) in Rust are
114 usually indicated by panics, which kill the whole current thread at the very
115 least. If your function has a non-trivial contract like this, that is
116 detected/enforced by panics, documenting it is very important.
123 If your function or method returns a `Result<T, E>`, then describing the
124 conditions under which it returns `Err(E)` is a nice thing to do. This is
125 slightly less important than `Panics`, because failure is encoded into the type
126 system, but it's still a good thing to do.
133 If your function is `unsafe`, you should explain which invariants the caller is
134 responsible for upholding.
142 /// let five = Rc::new(5);
147 Fourth, `Examples`. Include one or more examples of using your function or
148 method, and your users will love you for it. These examples go inside of
149 code block annotations, which we'll talk about in a moment, and can have
150 more than one section:
155 /// Simple `&str` patterns:
158 /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
159 /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
162 /// More complex patterns with a lambda:
165 /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
166 /// assert_eq!(v, vec!["abc", "def", "ghi"]);
171 Let's discuss the details of these code blocks.
173 #### Code block annotations
175 To write some Rust code in a comment, use the triple graves:
179 /// println!("Hello, world");
184 If you want something that's not Rust code, you can add an annotation:
188 /// printf("Hello, world\n");
193 This will highlight according to whatever language you're showing off.
194 If you're just showing plain text, choose `text`.
196 It's important to choose the correct annotation here, because `rustdoc` uses it
197 in an interesting way: It can be used to actually test your examples, so that
198 they don't get out of date. If you have some C code but `rustdoc` thinks it's
199 Rust because you left off the annotation, `rustdoc` will complain when trying to
200 generate the documentation.
202 ## Documentation as tests
204 Let's discuss our sample example documentation:
208 /// println!("Hello, world");
213 You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
214 automatically add a main() wrapper around your code, and in the right place.
221 /// let five = Rc::new(5);
226 This will end up testing:
231 let five = Rc::new(5);
235 Here's the full algorithm rustdoc uses to postprocess examples:
237 1. Any leading `#![foo]` attributes are left intact as crate attributes.
238 2. Some common `allow` attributes are inserted, including
239 `unused_variables`, `unused_assignments`, `unused_mut`,
240 `unused_attributes`, and `dead_code`. Small examples often trigger
242 3. If the example does not contain `extern crate`, then `extern crate
243 <mycrate>;` is inserted.
244 2. Finally, if the example does not contain `fn main`, the remainder of the
245 text is wrapped in `fn main() { your_code }`
247 Sometimes, this isn't enough, though. For example, all of these code samples
248 with `///` we've been talking about? The raw text:
251 /// Some documentation.
255 looks different than the output:
258 /// Some documentation.
262 Yes, that's right: you can add lines that start with `# `, and they will
263 be hidden from the output, but will be used when compiling your code. You
264 can use this to your advantage. In this case, documentation comments need
265 to apply to some kind of function, so if I want to show you just a
266 documentation comment, I need to add a little function definition below
267 it. At the same time, it's just there to satisfy the compiler, so hiding
268 it makes the example more clear. You can use this technique to explain
269 longer examples in detail, while still preserving the testability of your
270 documentation. For example, this code:
275 println!("{}", x + y);
278 Here's an explanation, rendered:
280 First, we set `x` to five:
285 # println!("{}", x + y);
288 Next, we set `y` to six:
293 # println!("{}", x + y);
296 Finally, we print the sum of `x` and `y`:
301 println!("{}", x + y);
304 Here's the same explanation, in raw text:
306 > First, we set `x` to five:
311 > # println!("{}", x + y);
314 > Next, we set `y` to six:
319 > # println!("{}", x + y);
322 > Finally, we print the sum of `x` and `y`:
327 > println!("{}", x + y);
330 By repeating all parts of the example, you can ensure that your example still
331 compiles, while only showing the parts that are relevant to that part of your
334 ### Documenting macros
336 Here’s an example of documenting a macro:
339 /// Panic with a given message unless an expression evaluates to true.
344 /// # #[macro_use] extern crate foo;
346 /// panic_unless!(1 + 1 == 2, “Math is broken.”);
351 /// # #[macro_use] extern crate foo;
353 /// panic_unless!(true == false, “I’m broken.”);
357 macro_rules! panic_unless {
358 ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
363 You’ll note three things: we need to add our own `extern crate` line, so that
364 we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
365 `main()` as well. Finally, a judicious use of `#` to comment out those two
366 things, so they don’t show up in the output.
368 ### Running documentation tests
370 To run the tests, either
373 $ rustdoc --test path/to/my/crate/root.rs
378 That's right, `cargo test` tests embedded documentation too. However,
379 `cargo test` will not test binary crates, only library ones. This is
380 due to the way `rustdoc` works: it links against the library to be tested,
381 but with a binary, there’s nothing to link to.
383 There are a few more annotations that are useful to help `rustdoc` do the right
384 thing when testing your code:
393 The `ignore` directive tells Rust to ignore your code. This is almost never
394 what you want, as it's the most generic. Instead, consider annotating it
395 with `text` if it's not code, or using `#`s to get a working example that
396 only shows the part you care about.
405 `should_panic` tells `rustdoc` that the code should compile correctly, but
406 not actually pass as a test.
411 /// println!("Hello, world");
417 The `no_run` attribute will compile your code, but not run it. This is
418 important for examples such as "Here's how to start up a network service,"
419 which you would want to make sure compile, but might run in an infinite loop!
421 ### Documenting modules
423 Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:
427 //! This is documentation for the `foo` module.
435 This is where you'll see `//!` used most often: for module documentation. If
436 you have a module in `foo.rs`, you'll often open its code and see this:
439 //! A module for using `foo`s.
441 //! The `foo` module contains a lot of useful functionality blah blah blah
444 ### Documentation comment style
446 Check out [RFC 505][rfc505] for full conventions around the style and format of
449 [rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md
451 ## Other documentation
453 All of this behavior works in non-Rust source files too. Because comments
454 are written in Markdown, they're often `.md` files.
456 When you write documentation in Markdown files, you don't need to prefix
457 the documentation with comments. For example:
465 /// let five = Rc::new(5);
478 let five = Rc::new(5);
482 when it's in a Markdown file. There is one wrinkle though: Markdown files need
483 to have a title like this:
488 This is the example documentation.
491 This `%` line needs to be the very first line of the file.
495 At a deeper level, documentation comments are sugar for documentation attributes:
505 are the same, as are these:
513 You won't often see this attribute used for writing documentation, but it
514 can be useful when changing some options, or when writing a macro.
518 `rustdoc` will show the documentation for a public re-export in both places:
526 This will create documentation for bar both inside the documentation for the
527 crate `foo`, as well as the documentation for your crate. It will use the same
528 documentation in both places.
530 This behavior can be suppressed with `no_inline`:
541 You can control a few aspects of the HTML that `rustdoc` generates through the
542 `#![doc]` version of the attribute:
545 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
546 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
547 html_root_url = "http://doc.rust-lang.org/")]
550 This sets a few different options, with a logo, favicon, and a root URL.
552 ## Generation options
554 `rustdoc` also contains a few other options on the command line, for further customization:
556 - `--html-in-header FILE`: includes the contents of FILE at the end of the
557 `<head>...</head>` section.
558 - `--html-before-content FILE`: includes the contents of FILE directly after
559 `<body>`, before the rendered content (including the search bar).
560 - `--html-after-content FILE`: includes the contents of FILE after all the rendered content.
564 The Markdown in documentation comments is placed without processing into
565 the final webpage. Be careful with literal HTML:
568 /// <script>alert(document.cookie)</script>