]>
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 |
b039eaaf | 48 | /// The `Option` type. See [the module level documentation](index.html) for more. |
c34b1796 AL |
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 | 59 | ```rust,ignore |
b039eaaf | 60 | /// The `Option` type. See [the module level documentation](index.html) for more. |
c34b1796 AL |
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 | 75 | This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is |
9cc50fc6 | 76 | correct; documentation comments apply to the thing after them, and there's |
e9174d1e | 77 | nothing 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 | ||
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 | 195 | This will highlight according to whatever language you're showing off. |
9cc50fc6 | 196 | If you're only showing plain text, choose `text`. |
c34b1796 AL |
197 | |
198 | It's important to choose the correct annotation here, because `rustdoc` uses it | |
e9174d1e SL |
199 | in an interesting way: It can be used to actually test your examples in a |
200 | library 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 | |
202 | complain when trying to generate the documentation. | |
c34b1796 AL |
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 | 215 | You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will |
92a42be0 SL |
216 | automatically add a `main()` wrapper around your code, using heuristics to attempt |
217 | to 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 | 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 | ||
b039eaaf | 237 | Here's the full algorithm rustdoc uses to preprocess examples: |
c34b1796 AL |
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 | |
92a42be0 SL |
245 | <mycrate>;` is inserted (note the lack of `#[macro_use]`). |
246 | 4. Finally, if the example does not contain `fn main`, the remainder of the | |
247 | text is wrapped in `fn main() { your_code }`. | |
248 | ||
249 | This generated `fn main` can be a problem! If you have `extern crate` or a `mod` | |
250 | statements in the example code that are referred to by `use` statements, they will | |
251 | fail 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 | |
253 | testing macros an explicit `main` is always required. It doesn't have to clutter | |
254 | up your docs, though -- keep reading! | |
255 | ||
256 | Sometimes this algorithm isn't enough, though. For example, all of these code samples | |
c34b1796 | 257 | with `///` 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 | 264 | looks different than the output: |
85aaf69f | 265 | |
62682a34 | 266 | ```rust |
c34b1796 AL |
267 | /// Some documentation. |
268 | # fn foo() {} | |
269 | ``` | |
270 | ||
271 | Yes, that's right: you can add lines that start with `# `, and they will | |
272 | be hidden from the output, but will be used when compiling your code. You | |
273 | can use this to your advantage. In this case, documentation comments need | |
274 | to apply to some kind of function, so if I want to show you just a | |
275 | documentation comment, I need to add a little function definition below | |
9cc50fc6 | 276 | it. At the same time, it's only there to satisfy the compiler, so hiding |
c34b1796 AL |
277 | it makes the example more clear. You can use this technique to explain |
278 | longer examples in detail, while still preserving the testability of your | |
b039eaaf | 279 | documentation. |
85aaf69f | 280 | |
b039eaaf | 281 | For example, imagine that we wanted to document this code: |
85aaf69f | 282 | |
62682a34 | 283 | ```rust |
c34b1796 | 284 | let x = 5; |
c34b1796 | 285 | let y = 6; |
c34b1796 AL |
286 | println!("{}", x + y); |
287 | ``` | |
288 | ||
b039eaaf | 289 | We 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 |
315 | To keep each code block testable, we want the whole program in each block, but |
316 | we don't want the reader to see every line every time. Here's what we put in | |
317 | our 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 |
345 | By repeating all parts of the example, you can ensure that your example still |
346 | compiles, while only showing the parts that are relevant to that part of your | |
347 | explanation. | |
348 | ||
349 | ### Documenting macros | |
350 | ||
351 | Here’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] | |
372 | macro_rules! panic_unless { | |
373 | ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } }); | |
374 | } | |
375 | # fn main() {} | |
376 | ``` | |
377 | ||
378 | You’ll note three things: we need to add our own `extern crate` line, so that | |
379 | we 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 | ||
383 | Another case where the use of `#` is handy is when you want to ignore | |
384 | error 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 | ||
392 | The problem is that `try!` returns a `Result<T, E>` and test functions | |
393 | don'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 | ||
409 | You can get around this by wrapping the code in a function. This catches | |
410 | and swallows the `Result<T, E>` when running tests on the docs. This | |
411 | pattern appears regularly in the standard library. | |
c34b1796 AL |
412 | |
413 | ### Running documentation tests | |
414 | ||
b039eaaf | 415 | To 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 |
423 | That's right, `cargo test` tests embedded documentation too. **However, |
424 | `cargo test` will not test binary crates, only library ones.** This is | |
bd371182 AL |
425 | due to the way `rustdoc` works: it links against the library to be tested, |
426 | but with a binary, there’s nothing to link to. | |
c34b1796 AL |
427 | |
428 | There are a few more annotations that are useful to help `rustdoc` do the right | |
429 | thing 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 |
438 | The `ignore` directive tells Rust to ignore your code. This is almost never |
439 | what you want, as it's the most generic. Instead, consider annotating it | |
440 | with `text` if it's not code, or using `#`s to get a working example that | |
441 | only 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 | |
451 | not 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 | ||
462 | The `no_run` attribute will compile your code, but not run it. This is | |
463 | important for examples such as "Here's how to start up a network service," | |
464 | which you would want to make sure compile, but might run in an infinite loop! | |
465 | ||
466 | ### Documenting modules | |
467 | ||
468 | Rust 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 |
471 | mod foo { |
472 | //! This is documentation for the `foo` module. | |
473 | //! | |
474 | //! # Examples | |
475 | ||
476 | // ... | |
85aaf69f SL |
477 | } |
478 | ``` | |
479 | ||
c34b1796 AL |
480 | This is where you'll see `//!` used most often: for module documentation. If |
481 | you 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 | ||
491 | Check out [RFC 505][rfc505] for full conventions around the style and format of | |
492 | documentation. | |
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 | ||
498 | All of this behavior works in non-Rust source files too. Because comments | |
499 | are written in Markdown, they're often `.md` files. | |
500 | ||
501 | When you write documentation in Markdown files, you don't need to prefix | |
502 | the 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 | 515 | is: |
85aaf69f | 516 | |
c34b1796 AL |
517 | ~~~markdown |
518 | # Examples | |
85aaf69f | 519 | |
c34b1796 AL |
520 | ``` |
521 | use std::rc::Rc; | |
85aaf69f | 522 | |
c34b1796 AL |
523 | let five = Rc::new(5); |
524 | ``` | |
85aaf69f SL |
525 | ~~~ |
526 | ||
c34b1796 AL |
527 | when it's in a Markdown file. There is one wrinkle though: Markdown files need |
528 | to have a title like this: | |
85aaf69f | 529 | |
c34b1796 AL |
530 | ```markdown |
531 | % The title | |
85aaf69f | 532 | |
c34b1796 AL |
533 | This is the example documentation. |
534 | ``` | |
85aaf69f | 535 | |
c34b1796 | 536 | This `%` line needs to be the very first line of the file. |
85aaf69f | 537 | |
c34b1796 | 538 | ## `doc` attributes |
85aaf69f | 539 | |
b039eaaf SL |
540 | At a deeper level, documentation comments are syntactic sugar for documentation |
541 | attributes: | |
c34b1796 | 542 | |
62682a34 | 543 | ```rust |
c34b1796 AL |
544 | /// this |
545 | # fn foo() {} | |
85aaf69f | 546 | |
c34b1796 AL |
547 | #[doc="this"] |
548 | # fn bar() {} | |
549 | ``` | |
550 | ||
551 | are the same, as are these: | |
552 | ||
62682a34 | 553 | ```rust |
c34b1796 AL |
554 | //! this |
555 | ||
b039eaaf | 556 | #![doc="this"] |
c34b1796 | 557 | ``` |
85aaf69f | 558 | |
c34b1796 AL |
559 | You won't often see this attribute used for writing documentation, but it |
560 | can 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 |
567 | extern crate foo; |
568 | ||
569 | pub use foo::bar; | |
570 | ``` | |
571 | ||
b039eaaf | 572 | This will create documentation for `bar` both inside the documentation for the |
c34b1796 AL |
573 | crate `foo`, as well as the documentation for your crate. It will use the same |
574 | documentation in both places. | |
85aaf69f | 575 | |
c34b1796 | 576 | This behavior can be suppressed with `no_inline`: |
85aaf69f | 577 | |
c34b1796 | 578 | ```ignore |
85aaf69f SL |
579 | extern crate foo; |
580 | ||
581 | #[doc(no_inline)] | |
582 | pub use foo::bar; | |
583 | ``` | |
c34b1796 | 584 | |
b039eaaf SL |
585 | ## Missing documentation |
586 | ||
587 | Sometimes you want to make sure that every single public thing in your project | |
588 | is documented, especially when you are working on a library. Rust allows you to | |
589 | to generate warnings or errors, when an item is missing documentation. | |
590 | To generate warnings you use `warn`: | |
591 | ||
592 | ```rust | |
593 | #![warn(missing_docs)] | |
594 | ``` | |
595 | ||
596 | And to generate errors you use `deny`: | |
597 | ||
598 | ```rust,ignore | |
599 | #![deny(missing_docs)] | |
600 | ``` | |
601 | ||
602 | There are cases where you want to disable these warnings/errors to explicitly | |
603 | leave something undocumented. This is done by using `allow`: | |
604 | ||
605 | ```rust | |
606 | #[allow(missing_docs)] | |
607 | struct Undocumented; | |
608 | ``` | |
609 | ||
610 | You might even want to hide items from the documentation completely: | |
611 | ||
612 | ```rust | |
613 | #[doc(hidden)] | |
614 | struct Hidden; | |
615 | ``` | |
616 | ||
c34b1796 AL |
617 | ### Controlling HTML |
618 | ||
619 | You 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 | ||
628 | This sets a few different options, with a logo, favicon, and a root URL. | |
629 | ||
92a42be0 SL |
630 | ### Configuring documentation tests |
631 | ||
632 | You can also configure the way that `rustdoc` tests your documentation examples | |
633 | through the `#![doc(test(..))]` attribute. | |
634 | ||
635 | ```rust | |
636 | #![doc(test(attr(allow(unused_variables), deny(warnings))))] | |
637 | ``` | |
638 | ||
639 | This allows unused variables within the examples, but will fail the test for any | |
640 | other 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 | ||
654 | The Markdown in documentation comments is placed without processing into | |
655 | the final webpage. Be careful with literal HTML: | |
656 | ||
657 | ```rust | |
658 | /// <script>alert(document.cookie)</script> | |
659 | # fn foo() {} | |
660 | ``` |