]>
Commit | Line | Data |
---|---|---|
85aaf69f SL |
1 | % Documentation |
2 | ||
c34b1796 AL |
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. | |
85aaf69f | 6 | |
c34b1796 | 7 | ## About `rustdoc` |
85aaf69f | 8 | |
c34b1796 AL |
9 | The Rust distribution includes a tool, `rustdoc`, that generates documentation. |
10 | `rustdoc` is also used by Cargo through `cargo doc`. | |
85aaf69f | 11 | |
c34b1796 AL |
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 | |
c1a9b12d SL |
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 | |
c34b1796 AL |
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 | ||
62682a34 | 47 | ```rust |
c34b1796 AL |
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), | |
85aaf69f | 54 | } |
c34b1796 AL |
55 | ``` |
56 | ||
57 | The above works, but this does not: | |
85aaf69f | 58 | |
c34b1796 AL |
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` | |
85aaf69f | 64 | } |
c34b1796 | 65 | ``` |
85aaf69f | 66 | |
c34b1796 | 67 | You'll get an error: |
85aaf69f | 68 | |
c34b1796 AL |
69 | ```text |
70 | hello.rs:4:1: 4:2 error: expected ident, found `}` | |
71 | hello.rs:4 } | |
72 | ^ | |
73 | ``` | |
85aaf69f | 74 | |
c34b1796 AL |
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. | |
85aaf69f | 78 | |
c34b1796 AL |
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: | |
85aaf69f | 84 | |
62682a34 | 85 | ```rust |
c34b1796 AL |
86 | /// Constructs a new `Rc<T>`. |
87 | # fn foo() {} | |
85aaf69f SL |
88 | ``` |
89 | ||
c34b1796 AL |
90 | The first line of a documentation comment should be a short summary of its |
91 | functionality. 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 |
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. | |
85aaf69f | 103 | |
c34b1796 | 104 | #### Special sections |
85aaf69f | 105 | |
c34b1796 | 106 | Next, are special sections. These are indicated with a header, `#`. There |
c1a9b12d | 107 | are four kinds of headers that are commonly used. They aren't special syntax, |
c34b1796 | 108 | just convention, for now. |
85aaf69f | 109 | |
62682a34 | 110 | ```rust |
c34b1796 AL |
111 | /// # Panics |
112 | # fn foo() {} | |
113 | ``` | |
85aaf69f | 114 | |
c34b1796 AL |
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. | |
85aaf69f | 119 | |
62682a34 | 120 | ```rust |
c34b1796 AL |
121 | /// # Failures |
122 | # fn foo() {} | |
123 | ``` | |
85aaf69f | 124 | |
c34b1796 AL |
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. | |
85aaf69f | 129 | |
62682a34 | 130 | ```rust |
c34b1796 AL |
131 | /// # Safety |
132 | # fn foo() {} | |
133 | ``` | |
85aaf69f | 134 | |
c34b1796 AL |
135 | If your function is `unsafe`, you should explain which invariants the caller is |
136 | responsible 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 | 149 | Fourth, `Examples`. Include one or more examples of using your function or |
c34b1796 AL |
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: | |
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 | 173 | Let's discuss the details of these code blocks. |
85aaf69f | 174 | |
c34b1796 | 175 | #### Code block annotations |
85aaf69f | 176 | |
c34b1796 | 177 | To 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 |
186 | If 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 AL |
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 | ||
62682a34 | 208 | ```rust |
c34b1796 AL |
209 | /// ``` |
210 | /// println!("Hello, world"); | |
211 | /// ``` | |
212 | # fn foo() {} | |
85aaf69f SL |
213 | ``` |
214 | ||
c34b1796 AL |
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: | |
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 | 228 | This will end up testing: |
85aaf69f | 229 | |
62682a34 | 230 | ```rust |
c34b1796 AL |
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 }` | |
85aaf69f | 248 | |
c34b1796 AL |
249 | Sometimes, this isn't enough, though. For example, all of these code samples |
250 | with `///` we've been talking about? The raw text: | |
85aaf69f | 251 | |
c34b1796 AL |
252 | ```text |
253 | /// Some documentation. | |
254 | # fn foo() {} | |
85aaf69f | 255 | ``` |
85aaf69f | 256 | |
c34b1796 | 257 | looks different than the output: |
85aaf69f | 258 | |
62682a34 | 259 | ```rust |
c34b1796 AL |
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 | ||
62682a34 | 274 | ```rust |
c34b1796 AL |
275 | let x = 5; |
276 | let y = 6; | |
277 | println!("{}", x + y); | |
278 | ``` | |
279 | ||
280 | Here's an explanation, rendered: | |
85aaf69f | 281 | |
c34b1796 | 282 | First, we set `x` to five: |
85aaf69f | 283 | |
62682a34 | 284 | ```rust |
c34b1796 AL |
285 | let x = 5; |
286 | # let y = 6; | |
287 | # println!("{}", x + y); | |
288 | ``` | |
289 | ||
290 | Next, we set `y` to six: | |
85aaf69f | 291 | |
62682a34 | 292 | ```rust |
c34b1796 AL |
293 | # let x = 5; |
294 | let y = 6; | |
295 | # println!("{}", x + y); | |
296 | ``` | |
85aaf69f | 297 | |
c34b1796 | 298 | Finally, we print the sum of `x` and `y`: |
85aaf69f | 299 | |
62682a34 | 300 | ```rust |
c34b1796 AL |
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: | |
85aaf69f | 339 | |
62682a34 | 340 | ```rust |
c34b1796 AL |
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 | /// # } | |
85aaf69f | 350 | /// ``` |
85aaf69f | 351 | /// |
c34b1796 AL |
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 | ||
c1a9b12d | 380 | That's right, `cargo test` tests embedded documentation too. However, |
bd371182 AL |
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. | |
c34b1796 AL |
384 | |
385 | There are a few more annotations that are useful to help `rustdoc` do the right | |
386 | thing when testing your code: | |
387 | ||
62682a34 | 388 | ```rust |
c34b1796 AL |
389 | /// ```ignore |
390 | /// fn foo() { | |
85aaf69f SL |
391 | /// ``` |
392 | # fn foo() {} | |
393 | ``` | |
394 | ||
c34b1796 AL |
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. | |
85aaf69f | 399 | |
62682a34 | 400 | ```rust |
c34b1796 AL |
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 | ||
62682a34 | 410 | ```rust |
c34b1796 AL |
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 | ||
62682a34 | 427 | ```rust |
c34b1796 AL |
428 | mod foo { |
429 | //! This is documentation for the `foo` module. | |
430 | //! | |
431 | //! # Examples | |
432 | ||
433 | // ... | |
85aaf69f SL |
434 | } |
435 | ``` | |
436 | ||
c34b1796 AL |
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 | ||
62682a34 | 440 | ```rust |
c34b1796 AL |
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. | |
85aaf69f | 450 | |
c34b1796 AL |
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 | ||
62682a34 | 461 | ```rust |
c34b1796 AL |
462 | /// # Examples |
463 | /// | |
464 | /// ``` | |
465 | /// use std::rc::Rc; | |
466 | /// | |
467 | /// let five = Rc::new(5); | |
468 | /// ``` | |
469 | # fn foo() {} | |
470 | ``` | |
85aaf69f | 471 | |
c34b1796 | 472 | is just |
85aaf69f | 473 | |
c34b1796 AL |
474 | ~~~markdown |
475 | # Examples | |
85aaf69f | 476 | |
c34b1796 AL |
477 | ``` |
478 | use std::rc::Rc; | |
85aaf69f | 479 | |
c34b1796 AL |
480 | let five = Rc::new(5); |
481 | ``` | |
85aaf69f SL |
482 | ~~~ |
483 | ||
c34b1796 AL |
484 | when it's in a Markdown file. There is one wrinkle though: Markdown files need |
485 | to have a title like this: | |
85aaf69f | 486 | |
c34b1796 AL |
487 | ```markdown |
488 | % The title | |
85aaf69f | 489 | |
c34b1796 AL |
490 | This is the example documentation. |
491 | ``` | |
85aaf69f | 492 | |
c34b1796 | 493 | This `%` line needs to be the very first line of the file. |
85aaf69f | 494 | |
c34b1796 | 495 | ## `doc` attributes |
85aaf69f | 496 | |
c34b1796 AL |
497 | At a deeper level, documentation comments are sugar for documentation attributes: |
498 | ||
62682a34 | 499 | ```rust |
c34b1796 AL |
500 | /// this |
501 | # fn foo() {} | |
85aaf69f | 502 | |
c34b1796 AL |
503 | #[doc="this"] |
504 | # fn bar() {} | |
505 | ``` | |
506 | ||
507 | are the same, as are these: | |
508 | ||
62682a34 | 509 | ```rust |
c34b1796 AL |
510 | //! this |
511 | ||
512 | #![doc="/// this"] | |
513 | ``` | |
85aaf69f | 514 | |
c34b1796 AL |
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. | |
85aaf69f | 517 | |
c34b1796 | 518 | ### Re-exports |
85aaf69f | 519 | |
c34b1796 AL |
520 | `rustdoc` will show the documentation for a public re-export in both places: |
521 | ||
522 | ```ignore | |
85aaf69f SL |
523 | extern crate foo; |
524 | ||
525 | pub use foo::bar; | |
526 | ``` | |
527 | ||
c34b1796 AL |
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. | |
85aaf69f | 531 | |
c34b1796 | 532 | This behavior can be suppressed with `no_inline`: |
85aaf69f | 533 | |
c34b1796 | 534 | ```ignore |
85aaf69f SL |
535 | extern crate foo; |
536 | ||
537 | #[doc(no_inline)] | |
538 | pub use foo::bar; | |
539 | ``` | |
c34b1796 AL |
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 | ||
62682a34 | 546 | ```rust |
c34b1796 AL |
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", | |
62682a34 | 549 | html_root_url = "http://doc.rust-lang.org/")] |
c34b1796 AL |
550 | ``` |
551 | ||
552 | This sets a few different options, with a logo, favicon, and a root URL. | |
553 | ||
554 | ## Generation options | |
555 | ||
bd371182 | 556 | `rustdoc` also contains a few other options on the command line, for further customization: |
c34b1796 AL |
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. | |
bd371182 AL |
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 | ``` |