]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/documentation.md
Auto merge of #26533 - nham:test-23305, r=alexcrichton
[rust.git] / src / doc / trpl / 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. That's the first thing
37 to notice about this annotation: it uses `///`, instead of `//`. The triple slash
38 indicates a documentation comment.
39
40 Documentation comments are written in Markdown.
41
42 Rust keeps track of these comments, and uses them when generating
43 documentation. This is important when documenting things like enums:
44
45 ```rust
46 /// The `Option` type. See [the module level documentation](../) for more.
47 enum Option<T> {
48     /// No value
49     None,
50     /// Some value `T`
51     Some(T),
52 }
53 ```
54
55 The above works, but this does not:
56
57 ```rust,ignore
58 /// The `Option` type. See [the module level documentation](../) for more.
59 enum Option<T> {
60     None, /// No value
61     Some(T), /// Some value `T`
62 }
63 ```
64
65 You'll get an error:
66
67 ```text
68 hello.rs:4:1: 4:2 error: expected ident, found `}`
69 hello.rs:4 }
70            ^
71 ```
72
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.
76
77 [rc-new]: http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new
78
79 ### Writing documentation comments
80
81 Anyway, let's cover each part of this comment in detail:
82
83 ```rust
84 /// Constructs a new `Rc<T>`.
85 # fn foo() {}
86 ```
87
88 The first line of a documentation comment should be a short summary of its
89 functionality. One sentence. Just the basics. High level.
90
91 ```rust
92 ///
93 /// Other details about constructing `Rc<T>`s, maybe describing complicated
94 /// semantics, maybe additional options, all kinds of stuff.
95 ///
96 # fn foo() {}
97 ```
98
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.
101
102 #### Special sections
103
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.
107
108 ```rust
109 /// # Panics
110 # fn foo() {}
111 ```
112
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.
117
118 ```rust
119 /// # Failures
120 # fn foo() {}
121 ```
122
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.
127
128 ```rust
129 /// # Safety
130 # fn foo() {}
131 ```
132
133 If your function is `unsafe`, you should explain which invariants the caller is
134 responsible for upholding.
135
136 ```rust
137 /// # Examples
138 ///
139 /// ```
140 /// use std::rc::Rc;
141 ///
142 /// let five = Rc::new(5);
143 /// ```
144 # fn foo() {}
145 ```
146
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:
151
152 ```rust
153 /// # Examples
154 ///
155 /// Simple `&str` patterns:
156 ///
157 /// ```
158 /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
159 /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
160 /// ```
161 ///
162 /// More complex patterns with a lambda:
163 ///
164 /// ```
165 /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
166 /// assert_eq!(v, vec!["abc", "def", "ghi"]);
167 /// ```
168 # fn foo() {}
169 ```
170
171 Let's discuss the details of these code blocks.
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 If you want something that's not Rust code, you can add an annotation:
185
186 ```rust
187 /// ```c
188 /// printf("Hello, world\n");
189 /// ```
190 # fn foo() {}
191 ```
192
193 This will highlight according to whatever language you're showing off.
194 If you're just showing plain text, choose `text`.
195
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.
201
202 ## Documentation as tests
203
204 Let's discuss our sample example documentation:
205
206 ```rust
207 /// ```
208 /// println!("Hello, world");
209 /// ```
210 # fn foo() {}
211 ```
212
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.
215 For example:
216
217 ```rust
218 /// ```
219 /// use std::rc::Rc;
220 ///
221 /// let five = Rc::new(5);
222 /// ```
223 # fn foo() {}
224 ```
225
226 This will end up testing:
227
228 ```rust
229 fn main() {
230     use std::rc::Rc;
231     let five = Rc::new(5);
232 }
233 ```
234
235 Here's the full algorithm rustdoc uses to postprocess examples:
236
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
241    these lints.
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 }`
246
247 Sometimes, this isn't enough, though. For example, all of these code samples
248 with `///` we've been talking about? The raw text:
249
250 ```text
251 /// Some documentation.
252 # fn foo() {}
253 ```
254
255 looks different than the output:
256
257 ```rust
258 /// Some documentation.
259 # fn foo() {}
260 ```
261
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:
271
272 ```rust
273 let x = 5;
274 let y = 6;
275 println!("{}", x + y);
276 ```
277
278 Here's an explanation, rendered:
279
280 First, we set `x` to five:
281
282 ```rust
283 let x = 5;
284 # let y = 6;
285 # println!("{}", x + y);
286 ```
287
288 Next, we set `y` to six:
289
290 ```rust
291 # let x = 5;
292 let y = 6;
293 # println!("{}", x + y);
294 ```
295
296 Finally, we print the sum of `x` and `y`:
297
298 ```rust
299 # let x = 5;
300 # let y = 6;
301 println!("{}", x + y);
302 ```
303
304 Here's the same explanation, in raw text:
305
306 > First, we set `x` to five:
307 >
308 > ```text
309 > let x = 5;
310 > # let y = 6;
311 > # println!("{}", x + y);
312 > ```
313 >
314 > Next, we set `y` to six:
315 >
316 > ```text
317 > # let x = 5;
318 > let y = 6;
319 > # println!("{}", x + y);
320 > ```
321 >
322 > Finally, we print the sum of `x` and `y`:
323 >
324 > ```text
325 > # let x = 5;
326 > # let y = 6;
327 > println!("{}", x + y);
328 > ```
329
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
332 explanation.
333
334 ### Documenting macros
335
336 Here’s an example of documenting a macro:
337
338 ```rust
339 /// Panic with a given message unless an expression evaluates to true.
340 ///
341 /// # Examples
342 ///
343 /// ```
344 /// # #[macro_use] extern crate foo;
345 /// # fn main() {
346 /// panic_unless!(1 + 1 == 2, “Math is broken.”);
347 /// # }
348 /// ```
349 ///
350 /// ```should_panic
351 /// # #[macro_use] extern crate foo;
352 /// # fn main() {
353 /// panic_unless!(true == false, “I’m broken.”);
354 /// # }
355 /// ```
356 #[macro_export]
357 macro_rules! panic_unless {
358     ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
359 }
360 # fn main() {}
361 ```
362
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.
367
368 ### Running documentation tests
369
370 To run the tests, either
371
372 ```bash
373 $ rustdoc --test path/to/my/crate/root.rs
374 # or
375 $ cargo test
376 ```
377
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.
382
383 There are a few more annotations that are useful to help `rustdoc` do the right
384 thing when testing your code:
385
386 ```rust
387 /// ```ignore
388 /// fn foo() {
389 /// ```
390 # fn foo() {}
391 ```
392
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.
397
398 ```rust
399 /// ```should_panic
400 /// assert!(false);
401 /// ```
402 # fn foo() {}
403 ```
404
405 `should_panic` tells `rustdoc` that the code should compile correctly, but
406 not actually pass as a test.
407
408 ```rust
409 /// ```no_run
410 /// loop {
411 ///     println!("Hello, world");
412 /// }
413 /// ```
414 # fn foo() {}
415 ```
416
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!
420
421 ### Documenting modules
422
423 Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:
424
425 ```rust
426 mod foo {
427     //! This is documentation for the `foo` module.
428     //!
429     //! # Examples
430
431     // ...
432 }
433 ```
434
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:
437
438 ```rust
439 //! A module for using `foo`s.
440 //!
441 //! The `foo` module contains a lot of useful functionality blah blah blah
442 ```
443
444 ### Documentation comment style
445
446 Check out [RFC 505][rfc505] for full conventions around the style and format of
447 documentation.
448
449 [rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md
450
451 ## Other documentation
452
453 All of this behavior works in non-Rust source files too. Because comments
454 are written in Markdown, they're often `.md` files.
455
456 When you write documentation in Markdown files, you don't need to prefix
457 the documentation with comments. For example:
458
459 ```rust
460 /// # Examples
461 ///
462 /// ```
463 /// use std::rc::Rc;
464 ///
465 /// let five = Rc::new(5);
466 /// ```
467 # fn foo() {}
468 ```
469
470 is just
471
472 ~~~markdown
473 # Examples
474
475 ```
476 use std::rc::Rc;
477
478 let five = Rc::new(5);
479 ```
480 ~~~
481
482 when it's in a Markdown file. There is one wrinkle though: Markdown files need
483 to have a title like this:
484
485 ```markdown
486 % The title
487
488 This is the example documentation.
489 ```
490
491 This `%` line needs to be the very first line of the file.
492
493 ## `doc` attributes
494
495 At a deeper level, documentation comments are sugar for documentation attributes:
496
497 ```rust
498 /// this
499 # fn foo() {}
500
501 #[doc="this"]
502 # fn bar() {}
503 ```
504
505 are the same, as are these:
506
507 ```rust
508 //! this
509
510 #![doc="/// this"]
511 ```
512
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.
515
516 ### Re-exports
517
518 `rustdoc` will show the documentation for a public re-export in both places:
519
520 ```ignore
521 extern crate foo;
522
523 pub use foo::bar;
524 ```
525
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.
529
530 This behavior can be suppressed with `no_inline`:
531
532 ```ignore
533 extern crate foo;
534
535 #[doc(no_inline)]
536 pub use foo::bar;
537 ```
538
539 ### Controlling HTML
540
541 You can control a few aspects of the HTML that `rustdoc` generates through the
542 `#![doc]` version of the attribute:
543
544 ```rust
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/")]
548 ```
549
550 This sets a few different options, with a logo, favicon, and a root URL.
551
552 ## Generation options
553
554 `rustdoc` also contains a few other options on the command line, for further customization:
555
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.
561
562 ## Security note
563
564 The Markdown in documentation comments is placed without processing into
565 the final webpage. Be careful with literal HTML:
566
567 ```rust
568 /// <script>alert(document.cookie)</script>
569 # fn foo() {}
570 ```