]> git.proxmox.com Git - rustc.git/blob - src/doc/trpl/documentation.md
Imported Upstream version 1.3.0+dfsg1
[rustc.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.
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](../) 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](../) 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 no
77 thing after that last comment.
78
79 [rc-new]: http://doc.rust-lang.org/nightly/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 /// # Failures
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 Let's discuss the details of these code blocks.
174
175 #### Code block annotations
176
177 To write some Rust code in a comment, use the triple graves:
178
179 ```rust
180 /// ```
181 /// println!("Hello, world");
182 /// ```
183 # fn foo() {}
184 ```
185
186 If you want something that's not Rust code, you can add an annotation:
187
188 ```rust
189 /// ```c
190 /// printf("Hello, world\n");
191 /// ```
192 # fn foo() {}
193 ```
194
195 This will highlight according to whatever language you're showing off.
196 If you're just showing plain text, choose `text`.
197
198 It's important to choose the correct annotation here, because `rustdoc` uses it
199 in an interesting way: It can be used to actually test your examples, so that
200 they don't get out of date. If you have some C code but `rustdoc` thinks it's
201 Rust because you left off the annotation, `rustdoc` will complain when trying to
202 generate the documentation.
203
204 ## Documentation as tests
205
206 Let's discuss our sample example documentation:
207
208 ```rust
209 /// ```
210 /// println!("Hello, world");
211 /// ```
212 # fn foo() {}
213 ```
214
215 You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
216 automatically add a main() wrapper around your code, and in the right place.
217 For example:
218
219 ```rust
220 /// ```
221 /// use std::rc::Rc;
222 ///
223 /// let five = Rc::new(5);
224 /// ```
225 # fn foo() {}
226 ```
227
228 This will end up testing:
229
230 ```rust
231 fn main() {
232 use std::rc::Rc;
233 let five = Rc::new(5);
234 }
235 ```
236
237 Here's the full algorithm rustdoc uses to postprocess examples:
238
239 1. Any leading `#![foo]` attributes are left intact as crate attributes.
240 2. 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.
244 3. If the example does not contain `extern crate`, then `extern crate
245 <mycrate>;` is inserted.
246 2. Finally, if the example does not contain `fn main`, the remainder of the
247 text is wrapped in `fn main() { your_code }`
248
249 Sometimes, this isn't enough, though. For example, all of these code samples
250 with `///` we've been talking about? The raw text:
251
252 ```text
253 /// Some documentation.
254 # fn foo() {}
255 ```
256
257 looks different than the output:
258
259 ```rust
260 /// Some documentation.
261 # fn foo() {}
262 ```
263
264 Yes, that's right: you can add lines that start with `# `, and they will
265 be hidden from the output, but will be used when compiling your code. You
266 can use this to your advantage. In this case, documentation comments need
267 to apply to some kind of function, so if I want to show you just a
268 documentation comment, I need to add a little function definition below
269 it. At the same time, it's just there to satisfy the compiler, so hiding
270 it makes the example more clear. You can use this technique to explain
271 longer examples in detail, while still preserving the testability of your
272 documentation. For example, this code:
273
274 ```rust
275 let x = 5;
276 let y = 6;
277 println!("{}", x + y);
278 ```
279
280 Here's an explanation, rendered:
281
282 First, we set `x` to five:
283
284 ```rust
285 let x = 5;
286 # let y = 6;
287 # println!("{}", x + y);
288 ```
289
290 Next, we set `y` to six:
291
292 ```rust
293 # let x = 5;
294 let y = 6;
295 # println!("{}", x + y);
296 ```
297
298 Finally, we print the sum of `x` and `y`:
299
300 ```rust
301 # let x = 5;
302 # let y = 6;
303 println!("{}", x + y);
304 ```
305
306 Here's the same explanation, in raw text:
307
308 > First, we set `x` to five:
309 >
310 > ```text
311 > let x = 5;
312 > # let y = 6;
313 > # println!("{}", x + y);
314 > ```
315 >
316 > Next, we set `y` to six:
317 >
318 > ```text
319 > # let x = 5;
320 > let y = 6;
321 > # println!("{}", x + y);
322 > ```
323 >
324 > Finally, we print the sum of `x` and `y`:
325 >
326 > ```text
327 > # let x = 5;
328 > # let y = 6;
329 > println!("{}", x + y);
330 > ```
331
332 By repeating all parts of the example, you can ensure that your example still
333 compiles, while only showing the parts that are relevant to that part of your
334 explanation.
335
336 ### Documenting macros
337
338 Here’s an example of documenting a macro:
339
340 ```rust
341 /// Panic with a given message unless an expression evaluates to true.
342 ///
343 /// # Examples
344 ///
345 /// ```
346 /// # #[macro_use] extern crate foo;
347 /// # fn main() {
348 /// panic_unless!(1 + 1 == 2, “Math is broken.”);
349 /// # }
350 /// ```
351 ///
352 /// ```should_panic
353 /// # #[macro_use] extern crate foo;
354 /// # fn main() {
355 /// panic_unless!(true == false, “I’m broken.”);
356 /// # }
357 /// ```
358 #[macro_export]
359 macro_rules! panic_unless {
360 ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
361 }
362 # fn main() {}
363 ```
364
365 You’ll note three things: we need to add our own `extern crate` line, so that
366 we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
367 `main()` as well. Finally, a judicious use of `#` to comment out those two
368 things, so they don’t show up in the output.
369
370 ### Running documentation tests
371
372 To run the tests, either
373
374 ```bash
375 $ rustdoc --test path/to/my/crate/root.rs
376 # or
377 $ cargo test
378 ```
379
380 That's right, `cargo test` tests embedded documentation too. However,
381 `cargo test` will not test binary crates, only library ones. This is
382 due to the way `rustdoc` works: it links against the library to be tested,
383 but with a binary, there’s nothing to link to.
384
385 There are a few more annotations that are useful to help `rustdoc` do the right
386 thing when testing your code:
387
388 ```rust
389 /// ```ignore
390 /// fn foo() {
391 /// ```
392 # fn foo() {}
393 ```
394
395 The `ignore` directive tells Rust to ignore your code. This is almost never
396 what you want, as it's the most generic. Instead, consider annotating it
397 with `text` if it's not code, or using `#`s to get a working example that
398 only shows the part you care about.
399
400 ```rust
401 /// ```should_panic
402 /// assert!(false);
403 /// ```
404 # fn foo() {}
405 ```
406
407 `should_panic` tells `rustdoc` that the code should compile correctly, but
408 not actually pass as a test.
409
410 ```rust
411 /// ```no_run
412 /// loop {
413 /// println!("Hello, world");
414 /// }
415 /// ```
416 # fn foo() {}
417 ```
418
419 The `no_run` attribute will compile your code, but not run it. This is
420 important for examples such as "Here's how to start up a network service,"
421 which you would want to make sure compile, but might run in an infinite loop!
422
423 ### Documenting modules
424
425 Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:
426
427 ```rust
428 mod foo {
429 //! This is documentation for the `foo` module.
430 //!
431 //! # Examples
432
433 // ...
434 }
435 ```
436
437 This is where you'll see `//!` used most often: for module documentation. If
438 you have a module in `foo.rs`, you'll often open its code and see this:
439
440 ```rust
441 //! A module for using `foo`s.
442 //!
443 //! The `foo` module contains a lot of useful functionality blah blah blah
444 ```
445
446 ### Documentation comment style
447
448 Check out [RFC 505][rfc505] for full conventions around the style and format of
449 documentation.
450
451 [rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md
452
453 ## Other documentation
454
455 All of this behavior works in non-Rust source files too. Because comments
456 are written in Markdown, they're often `.md` files.
457
458 When you write documentation in Markdown files, you don't need to prefix
459 the documentation with comments. For example:
460
461 ```rust
462 /// # Examples
463 ///
464 /// ```
465 /// use std::rc::Rc;
466 ///
467 /// let five = Rc::new(5);
468 /// ```
469 # fn foo() {}
470 ```
471
472 is just
473
474 ~~~markdown
475 # Examples
476
477 ```
478 use std::rc::Rc;
479
480 let five = Rc::new(5);
481 ```
482 ~~~
483
484 when it's in a Markdown file. There is one wrinkle though: Markdown files need
485 to have a title like this:
486
487 ```markdown
488 % The title
489
490 This is the example documentation.
491 ```
492
493 This `%` line needs to be the very first line of the file.
494
495 ## `doc` attributes
496
497 At a deeper level, documentation comments are sugar for documentation attributes:
498
499 ```rust
500 /// this
501 # fn foo() {}
502
503 #[doc="this"]
504 # fn bar() {}
505 ```
506
507 are the same, as are these:
508
509 ```rust
510 //! this
511
512 #![doc="/// this"]
513 ```
514
515 You won't often see this attribute used for writing documentation, but it
516 can be useful when changing some options, or when writing a macro.
517
518 ### Re-exports
519
520 `rustdoc` will show the documentation for a public re-export in both places:
521
522 ```ignore
523 extern crate foo;
524
525 pub use foo::bar;
526 ```
527
528 This will create documentation for bar both inside the documentation for the
529 crate `foo`, as well as the documentation for your crate. It will use the same
530 documentation in both places.
531
532 This behavior can be suppressed with `no_inline`:
533
534 ```ignore
535 extern crate foo;
536
537 #[doc(no_inline)]
538 pub use foo::bar;
539 ```
540
541 ### Controlling HTML
542
543 You can control a few aspects of the HTML that `rustdoc` generates through the
544 `#![doc]` version of the attribute:
545
546 ```rust
547 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
548 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
549 html_root_url = "http://doc.rust-lang.org/")]
550 ```
551
552 This sets a few different options, with a logo, favicon, and a root URL.
553
554 ## Generation options
555
556 `rustdoc` also contains a few other options on the command line, for further customization:
557
558 - `--html-in-header FILE`: includes the contents of FILE at the end of the
559 `<head>...</head>` section.
560 - `--html-before-content FILE`: includes the contents of FILE directly after
561 `<body>`, before the rendered content (including the search bar).
562 - `--html-after-content FILE`: includes the contents of FILE after all the rendered content.
563
564 ## Security note
565
566 The Markdown in documentation comments is placed without processing into
567 the final webpage. Be careful with literal HTML:
568
569 ```rust
570 /// <script>alert(document.cookie)</script>
571 # fn foo() {}
572 ```