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