]> git.proxmox.com Git - rustc.git/blame - src/doc/book/documentation.md
Imported Upstream version 1.7.0+dfsg1
[rustc.git] / src / doc / book / documentation.md
CommitLineData
85aaf69f
SL
1% Documentation
2
c34b1796
AL
3Documentation is an important part of any software project, and it's
4first-class in Rust. Let's talk about the tooling Rust gives you to
5document your project.
85aaf69f 6
c34b1796 7## About `rustdoc`
85aaf69f 8
c34b1796
AL
9The Rust distribution includes a tool, `rustdoc`, that generates documentation.
10`rustdoc` is also used by Cargo through `cargo doc`.
85aaf69f 11
c34b1796
AL
12Documentation can be generated in two ways: from source code, and from
13standalone Markdown files.
14
15## Documenting source code
16
17The primary way of documenting a Rust project is through annotating the source
18code. You can use documentation comments for this purpose:
19
20```rust,ignore
21/// Constructs a new `Rc<T>`.
22///
23/// # Examples
24///
25/// ```
26/// use std::rc::Rc;
27///
28/// let five = Rc::new(5);
29/// ```
30pub fn new(value: T) -> Rc<T> {
31 // implementation goes here
32}
33```
34
35This code generates documentation that looks [like this][rc-new]. I've left the
c1a9b12d
SL
36implementation out, with a regular comment in its place.
37
38The first thing to notice about this annotation is that it uses
39`///` instead of `//`. The triple slash
c34b1796
AL
40indicates a documentation comment.
41
42Documentation comments are written in Markdown.
43
44Rust keeps track of these comments, and uses them when generating
45documentation. This is important when documenting things like enums:
46
62682a34 47```rust
b039eaaf 48/// The `Option` type. See [the module level documentation](index.html) for more.
c34b1796
AL
49enum Option<T> {
50 /// No value
51 None,
52 /// Some value `T`
53 Some(T),
85aaf69f 54}
c34b1796
AL
55```
56
57The above works, but this does not:
85aaf69f 58
c34b1796 59```rust,ignore
b039eaaf 60/// The `Option` type. See [the module level documentation](index.html) for more.
c34b1796
AL
61enum Option<T> {
62 None, /// No value
63 Some(T), /// Some value `T`
85aaf69f 64}
c34b1796 65```
85aaf69f 66
c34b1796 67You'll get an error:
85aaf69f 68
c34b1796
AL
69```text
70hello.rs:4:1: 4:2 error: expected ident, found `}`
71hello.rs:4 }
72 ^
73```
85aaf69f 74
c34b1796 75This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
9cc50fc6 76correct; documentation comments apply to the thing after them, and there's
e9174d1e 77nothing after that last comment.
85aaf69f 78
e9174d1e 79[rc-new]: https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new
c34b1796
AL
80
81### Writing documentation comments
82
83Anyway, let's cover each part of this comment in detail:
85aaf69f 84
62682a34 85```rust
c34b1796
AL
86/// Constructs a new `Rc<T>`.
87# fn foo() {}
85aaf69f
SL
88```
89
c34b1796
AL
90The first line of a documentation comment should be a short summary of its
91functionality. One sentence. Just the basics. High level.
85aaf69f 92
62682a34 93```rust
85aaf69f 94///
c34b1796
AL
95/// Other details about constructing `Rc<T>`s, maybe describing complicated
96/// semantics, maybe additional options, all kinds of stuff.
97///
98# fn foo() {}
99```
85aaf69f 100
c34b1796
AL
101Our original example had just a summary line, but if we had more things to say,
102we could have added more explanation in a new paragraph.
85aaf69f 103
c34b1796 104#### Special sections
85aaf69f 105
c34b1796 106Next, are special sections. These are indicated with a header, `#`. There
c1a9b12d 107are four kinds of headers that are commonly used. They aren't special syntax,
c34b1796 108just convention, for now.
85aaf69f 109
62682a34 110```rust
c34b1796
AL
111/// # Panics
112# fn foo() {}
113```
85aaf69f 114
c34b1796
AL
115Unrecoverable misuses of a function (i.e. programming errors) in Rust are
116usually indicated by panics, which kill the whole current thread at the very
117least. If your function has a non-trivial contract like this, that is
118detected/enforced by panics, documenting it is very important.
85aaf69f 119
62682a34 120```rust
c34b1796
AL
121/// # Failures
122# fn foo() {}
123```
85aaf69f 124
c34b1796
AL
125If your function or method returns a `Result<T, E>`, then describing the
126conditions under which it returns `Err(E)` is a nice thing to do. This is
127slightly less important than `Panics`, because failure is encoded into the type
128system, but it's still a good thing to do.
85aaf69f 129
62682a34 130```rust
c34b1796
AL
131/// # Safety
132# fn foo() {}
133```
85aaf69f 134
c34b1796
AL
135If your function is `unsafe`, you should explain which invariants the caller is
136responsible for upholding.
85aaf69f 137
62682a34 138```rust
c34b1796
AL
139/// # Examples
140///
141/// ```
142/// use std::rc::Rc;
143///
144/// let five = Rc::new(5);
145/// ```
146# fn foo() {}
147```
85aaf69f 148
c1a9b12d 149Fourth, `Examples`. Include one or more examples of using your function or
c34b1796
AL
150method, and your users will love you for it. These examples go inside of
151code block annotations, which we'll talk about in a moment, and can have
152more than one section:
85aaf69f 153
62682a34 154```rust
c34b1796
AL
155/// # Examples
156///
157/// Simple `&str` patterns:
158///
159/// ```
160/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
161/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
162/// ```
163///
164/// More complex patterns with a lambda:
165///
166/// ```
167/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
168/// assert_eq!(v, vec!["abc", "def", "ghi"]);
169/// ```
170# fn foo() {}
171```
85aaf69f 172
c34b1796 173Let's discuss the details of these code blocks.
85aaf69f 174
c34b1796 175#### Code block annotations
85aaf69f 176
c34b1796 177To write some Rust code in a comment, use the triple graves:
85aaf69f 178
62682a34 179```rust
c34b1796
AL
180/// ```
181/// println!("Hello, world");
182/// ```
183# fn foo() {}
85aaf69f
SL
184```
185
c34b1796
AL
186If you want something that's not Rust code, you can add an annotation:
187
62682a34 188```rust
c34b1796
AL
189/// ```c
190/// printf("Hello, world\n");
191/// ```
192# fn foo() {}
85aaf69f
SL
193```
194
c34b1796 195This will highlight according to whatever language you're showing off.
9cc50fc6 196If you're only showing plain text, choose `text`.
c34b1796
AL
197
198It's important to choose the correct annotation here, because `rustdoc` uses it
e9174d1e
SL
199in an interesting way: It can be used to actually test your examples in a
200library crate, so that they don't get out of date. If you have some C code but
201`rustdoc` thinks it's Rust because you left off the annotation, `rustdoc` will
202complain when trying to generate the documentation.
c34b1796
AL
203
204## Documentation as tests
205
206Let's discuss our sample example documentation:
207
62682a34 208```rust
c34b1796
AL
209/// ```
210/// println!("Hello, world");
211/// ```
212# fn foo() {}
85aaf69f
SL
213```
214
c34b1796 215You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
92a42be0
SL
216automatically add a `main()` wrapper around your code, using heuristics to attempt
217to put it in the right place. For example:
85aaf69f 218
62682a34 219```rust
c34b1796
AL
220/// ```
221/// use std::rc::Rc;
222///
223/// let five = Rc::new(5);
224/// ```
225# fn foo() {}
226```
85aaf69f 227
c34b1796 228This will end up testing:
85aaf69f 229
62682a34 230```rust
c34b1796
AL
231fn main() {
232 use std::rc::Rc;
233 let five = Rc::new(5);
234}
235```
236
b039eaaf 237Here's the full algorithm rustdoc uses to preprocess examples:
c34b1796
AL
238
2391. Any leading `#![foo]` attributes are left intact as crate attributes.
2402. Some common `allow` attributes are inserted, including
241 `unused_variables`, `unused_assignments`, `unused_mut`,
242 `unused_attributes`, and `dead_code`. Small examples often trigger
243 these lints.
2443. If the example does not contain `extern crate`, then `extern crate
92a42be0
SL
245 <mycrate>;` is inserted (note the lack of `#[macro_use]`).
2464. Finally, if the example does not contain `fn main`, the remainder of the
247 text is wrapped in `fn main() { your_code }`.
248
249This generated `fn main` can be a problem! If you have `extern crate` or a `mod`
250statements in the example code that are referred to by `use` statements, they will
251fail to resolve unless you include at least `fn main() {}` to inhibit step 4.
252`#[macro_use] extern crate` also does not work except at the crate root, so when
253testing macros an explicit `main` is always required. It doesn't have to clutter
254up your docs, though -- keep reading!
255
256Sometimes this algorithm isn't enough, though. For example, all of these code samples
c34b1796 257with `///` we've been talking about? The raw text:
85aaf69f 258
c34b1796
AL
259```text
260/// Some documentation.
261# fn foo() {}
85aaf69f 262```
85aaf69f 263
c34b1796 264looks different than the output:
85aaf69f 265
62682a34 266```rust
c34b1796
AL
267/// Some documentation.
268# fn foo() {}
269```
270
271Yes, that's right: you can add lines that start with `# `, and they will
272be hidden from the output, but will be used when compiling your code. You
273can use this to your advantage. In this case, documentation comments need
274to apply to some kind of function, so if I want to show you just a
275documentation comment, I need to add a little function definition below
9cc50fc6 276it. At the same time, it's only there to satisfy the compiler, so hiding
c34b1796
AL
277it makes the example more clear. You can use this technique to explain
278longer examples in detail, while still preserving the testability of your
b039eaaf 279documentation.
85aaf69f 280
b039eaaf 281For example, imagine that we wanted to document this code:
85aaf69f 282
62682a34 283```rust
c34b1796 284let x = 5;
c34b1796 285let y = 6;
c34b1796
AL
286println!("{}", x + y);
287```
288
b039eaaf 289We might want the documentation to end up looking like this:
c34b1796
AL
290
291> First, we set `x` to five:
292>
b039eaaf 293> ```rust
c34b1796
AL
294> let x = 5;
295> # let y = 6;
296> # println!("{}", x + y);
297> ```
298>
299> Next, we set `y` to six:
300>
b039eaaf 301> ```rust
c34b1796
AL
302> # let x = 5;
303> let y = 6;
304> # println!("{}", x + y);
305> ```
306>
307> Finally, we print the sum of `x` and `y`:
308>
b039eaaf 309> ```rust
c34b1796
AL
310> # let x = 5;
311> # let y = 6;
312> println!("{}", x + y);
313> ```
314
b039eaaf
SL
315To keep each code block testable, we want the whole program in each block, but
316we don't want the reader to see every line every time. Here's what we put in
317our source code:
318
319```text
320 First, we set `x` to five:
321
322 ```text
323 let x = 5;
324 # let y = 6;
325 # println!("{}", x + y);
326 ```
327
328 Next, we set `y` to six:
329
330 ```text
331 # let x = 5;
332 let y = 6;
333 # println!("{}", x + y);
334 ```
335
336 Finally, we print the sum of `x` and `y`:
337
338 ```text
339 # let x = 5;
340 # let y = 6;
341 println!("{}", x + y);
342 ```
343```
344
c34b1796
AL
345By repeating all parts of the example, you can ensure that your example still
346compiles, while only showing the parts that are relevant to that part of your
347explanation.
348
349### Documenting macros
350
351Here’s an example of documenting a macro:
85aaf69f 352
62682a34 353```rust
c34b1796
AL
354/// Panic with a given message unless an expression evaluates to true.
355///
356/// # Examples
357///
358/// ```
359/// # #[macro_use] extern crate foo;
360/// # fn main() {
361/// panic_unless!(1 + 1 == 2, “Math is broken.”);
362/// # }
85aaf69f 363/// ```
85aaf69f 364///
c34b1796
AL
365/// ```should_panic
366/// # #[macro_use] extern crate foo;
367/// # fn main() {
368/// panic_unless!(true == false, “I’m broken.”);
369/// # }
370/// ```
371#[macro_export]
372macro_rules! panic_unless {
373 ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
374}
375# fn main() {}
376```
377
378You’ll note three things: we need to add our own `extern crate` line, so that
379we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
92a42be0
SL
380`main()` as well (for reasons discussed above). Finally, a judicious use of
381`#` to comment out those two things, so they don’t show up in the output.
382
383Another case where the use of `#` is handy is when you want to ignore
384error handling. Lets say you want the following,
385
386```rust,ignore
387/// use std::io;
9cc50fc6 388/// let mut input = String::new();
92a42be0
SL
389/// try!(io::stdin().read_line(&mut input));
390```
391
392The problem is that `try!` returns a `Result<T, E>` and test functions
393don't return anything so this will give a mismatched types error.
394
395```rust,ignore
396/// A doc test using try!
397///
398/// ```
399/// use std::io;
400/// # fn foo() -> io::Result<()> {
9cc50fc6 401/// let mut input = String::new();
92a42be0
SL
402/// try!(io::stdin().read_line(&mut input));
403/// # Ok(())
404/// # }
405/// ```
406# fn foo() {}
407```
408
409You can get around this by wrapping the code in a function. This catches
410and swallows the `Result<T, E>` when running tests on the docs. This
411pattern appears regularly in the standard library.
c34b1796
AL
412
413### Running documentation tests
414
b039eaaf 415To run the tests, either:
c34b1796
AL
416
417```bash
418$ rustdoc --test path/to/my/crate/root.rs
419# or
420$ cargo test
421```
422
e9174d1e
SL
423That's right, `cargo test` tests embedded documentation too. **However,
424`cargo test` will not test binary crates, only library ones.** This is
bd371182
AL
425due to the way `rustdoc` works: it links against the library to be tested,
426but with a binary, there’s nothing to link to.
c34b1796
AL
427
428There are a few more annotations that are useful to help `rustdoc` do the right
429thing when testing your code:
430
62682a34 431```rust
c34b1796
AL
432/// ```ignore
433/// fn foo() {
85aaf69f
SL
434/// ```
435# fn foo() {}
436```
437
c34b1796
AL
438The `ignore` directive tells Rust to ignore your code. This is almost never
439what you want, as it's the most generic. Instead, consider annotating it
440with `text` if it's not code, or using `#`s to get a working example that
441only shows the part you care about.
85aaf69f 442
62682a34 443```rust
c34b1796
AL
444/// ```should_panic
445/// assert!(false);
446/// ```
447# fn foo() {}
448```
449
450`should_panic` tells `rustdoc` that the code should compile correctly, but
451not actually pass as a test.
452
62682a34 453```rust
c34b1796
AL
454/// ```no_run
455/// loop {
456/// println!("Hello, world");
457/// }
458/// ```
459# fn foo() {}
460```
461
462The `no_run` attribute will compile your code, but not run it. This is
463important for examples such as "Here's how to start up a network service,"
464which you would want to make sure compile, but might run in an infinite loop!
465
466### Documenting modules
467
468Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:
469
62682a34 470```rust
c34b1796
AL
471mod foo {
472 //! This is documentation for the `foo` module.
473 //!
474 //! # Examples
475
476 // ...
85aaf69f
SL
477}
478```
479
c34b1796
AL
480This is where you'll see `//!` used most often: for module documentation. If
481you have a module in `foo.rs`, you'll often open its code and see this:
482
62682a34 483```rust
c34b1796
AL
484//! A module for using `foo`s.
485//!
486//! The `foo` module contains a lot of useful functionality blah blah blah
487```
488
489### Documentation comment style
490
491Check out [RFC 505][rfc505] for full conventions around the style and format of
492documentation.
85aaf69f 493
c34b1796
AL
494[rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md
495
496## Other documentation
497
498All of this behavior works in non-Rust source files too. Because comments
499are written in Markdown, they're often `.md` files.
500
501When you write documentation in Markdown files, you don't need to prefix
502the documentation with comments. For example:
503
62682a34 504```rust
c34b1796
AL
505/// # Examples
506///
507/// ```
508/// use std::rc::Rc;
509///
510/// let five = Rc::new(5);
511/// ```
512# fn foo() {}
513```
85aaf69f 514
9cc50fc6 515is:
85aaf69f 516
c34b1796
AL
517~~~markdown
518# Examples
85aaf69f 519
c34b1796
AL
520```
521use std::rc::Rc;
85aaf69f 522
c34b1796
AL
523let five = Rc::new(5);
524```
85aaf69f
SL
525~~~
526
c34b1796
AL
527when it's in a Markdown file. There is one wrinkle though: Markdown files need
528to have a title like this:
85aaf69f 529
c34b1796
AL
530```markdown
531% The title
85aaf69f 532
c34b1796
AL
533This is the example documentation.
534```
85aaf69f 535
c34b1796 536This `%` line needs to be the very first line of the file.
85aaf69f 537
c34b1796 538## `doc` attributes
85aaf69f 539
b039eaaf
SL
540At a deeper level, documentation comments are syntactic sugar for documentation
541attributes:
c34b1796 542
62682a34 543```rust
c34b1796
AL
544/// this
545# fn foo() {}
85aaf69f 546
c34b1796
AL
547#[doc="this"]
548# fn bar() {}
549```
550
551are the same, as are these:
552
62682a34 553```rust
c34b1796
AL
554//! this
555
b039eaaf 556#![doc="this"]
c34b1796 557```
85aaf69f 558
c34b1796
AL
559You won't often see this attribute used for writing documentation, but it
560can be useful when changing some options, or when writing a macro.
85aaf69f 561
c34b1796 562### Re-exports
85aaf69f 563
c34b1796
AL
564`rustdoc` will show the documentation for a public re-export in both places:
565
566```ignore
85aaf69f
SL
567extern crate foo;
568
569pub use foo::bar;
570```
571
b039eaaf 572This will create documentation for `bar` both inside the documentation for the
c34b1796
AL
573crate `foo`, as well as the documentation for your crate. It will use the same
574documentation in both places.
85aaf69f 575
c34b1796 576This behavior can be suppressed with `no_inline`:
85aaf69f 577
c34b1796 578```ignore
85aaf69f
SL
579extern crate foo;
580
581#[doc(no_inline)]
582pub use foo::bar;
583```
c34b1796 584
b039eaaf
SL
585## Missing documentation
586
587Sometimes you want to make sure that every single public thing in your project
588is documented, especially when you are working on a library. Rust allows you to
589to generate warnings or errors, when an item is missing documentation.
590To generate warnings you use `warn`:
591
592```rust
593#![warn(missing_docs)]
594```
595
596And to generate errors you use `deny`:
597
598```rust,ignore
599#![deny(missing_docs)]
600```
601
602There are cases where you want to disable these warnings/errors to explicitly
603leave something undocumented. This is done by using `allow`:
604
605```rust
606#[allow(missing_docs)]
607struct Undocumented;
608```
609
610You might even want to hide items from the documentation completely:
611
612```rust
613#[doc(hidden)]
614struct Hidden;
615```
616
c34b1796
AL
617### Controlling HTML
618
619You can control a few aspects of the HTML that `rustdoc` generates through the
620`#![doc]` version of the attribute:
621
62682a34 622```rust
e9174d1e
SL
623#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
624 html_favicon_url = "https://www.rust-lang.org/favicon.ico",
625 html_root_url = "https://doc.rust-lang.org/")]
c34b1796
AL
626```
627
628This sets a few different options, with a logo, favicon, and a root URL.
629
92a42be0
SL
630### Configuring documentation tests
631
632You can also configure the way that `rustdoc` tests your documentation examples
633through the `#![doc(test(..))]` attribute.
634
635```rust
636#![doc(test(attr(allow(unused_variables), deny(warnings))))]
637```
638
639This allows unused variables within the examples, but will fail the test for any
640other lint warning thrown.
641
c34b1796
AL
642## Generation options
643
bd371182 644`rustdoc` also contains a few other options on the command line, for further customization:
c34b1796
AL
645
646- `--html-in-header FILE`: includes the contents of FILE at the end of the
647 `<head>...</head>` section.
648- `--html-before-content FILE`: includes the contents of FILE directly after
649 `<body>`, before the rendered content (including the search bar).
650- `--html-after-content FILE`: includes the contents of FILE after all the rendered content.
bd371182
AL
651
652## Security note
653
654The Markdown in documentation comments is placed without processing into
655the final webpage. Be careful with literal HTML:
656
657```rust
658/// <script>alert(document.cookie)</script>
659# fn foo() {}
660```