]> git.proxmox.com Git - rustc.git/blame - src/doc/trpl/documentation.md
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / doc / trpl / documentation.md
CommitLineData
85aaf69f
SL
1% Documentation
2
c34b1796
AL
3Documentation is an important part of any software project, and it's
4first-class in Rust. Let's talk about the tooling Rust gives you to
5document your project.
85aaf69f 6
c34b1796 7## About `rustdoc`
85aaf69f 8
c34b1796
AL
9The Rust distribution includes a tool, `rustdoc`, that generates documentation.
10`rustdoc` is also used by Cargo through `cargo doc`.
85aaf69f 11
c34b1796
AL
12Documentation can be generated in two ways: from source code, and from
13standalone Markdown files.
14
15## Documenting source code
16
17The primary way of documenting a Rust project is through annotating the source
18code. 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/// ```
30pub fn new(value: T) -> Rc<T> {
31 // implementation goes here
32}
33```
34
35This code generates documentation that looks [like this][rc-new]. I've left the
c1a9b12d
SL
36implementation out, with a regular comment in its place.
37
38The first thing to notice about this annotation is that it uses
39`///` instead of `//`. The triple slash
c34b1796
AL
40indicates a documentation comment.
41
42Documentation comments are written in Markdown.
43
44Rust keeps track of these comments, and uses them when generating
45documentation. 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.
49enum Option<T> {
50 /// No value
51 None,
52 /// Some value `T`
53 Some(T),
85aaf69f 54}
c34b1796
AL
55```
56
57The above works, but this does not:
85aaf69f 58
c34b1796
AL
59```rust,ignore
60/// The `Option` type. See [the module level documentation](../) for more.
61enum Option<T> {
62 None, /// No value
63 Some(T), /// Some value `T`
85aaf69f 64}
c34b1796 65```
85aaf69f 66
c34b1796 67You'll get an error:
85aaf69f 68
c34b1796
AL
69```text
70hello.rs:4:1: 4:2 error: expected ident, found `}`
71hello.rs:4 }
72 ^
73```
85aaf69f 74
c34b1796
AL
75This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
76correct: documentation comments apply to the thing after them, and there's no
77thing 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
83Anyway, 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
90The first line of a documentation comment should be a short summary of its
91functionality. 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
101Our original example had just a summary line, but if we had more things to say,
102we could have added more explanation in a new paragraph.
85aaf69f 103
c34b1796 104#### Special sections
85aaf69f 105
c34b1796 106Next, are special sections. These are indicated with a header, `#`. There
c1a9b12d 107are four kinds of headers that are commonly used. They aren't special syntax,
c34b1796 108just convention, for now.
85aaf69f 109
62682a34 110```rust
c34b1796
AL
111/// # Panics
112# fn foo() {}
113```
85aaf69f 114
c34b1796
AL
115Unrecoverable misuses of a function (i.e. programming errors) in Rust are
116usually indicated by panics, which kill the whole current thread at the very
117least. If your function has a non-trivial contract like this, that is
118detected/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
125If your function or method returns a `Result<T, E>`, then describing the
126conditions under which it returns `Err(E)` is a nice thing to do. This is
127slightly less important than `Panics`, because failure is encoded into the type
128system, 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
135If your function is `unsafe`, you should explain which invariants the caller is
136responsible 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 149Fourth, `Examples`. Include one or more examples of using your function or
c34b1796
AL
150method, and your users will love you for it. These examples go inside of
151code block annotations, which we'll talk about in a moment, and can have
152more 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 173Let's discuss the details of these code blocks.
85aaf69f 174
c34b1796 175#### Code block annotations
85aaf69f 176
c34b1796 177To 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
186If 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
195This will highlight according to whatever language you're showing off.
196If you're just showing plain text, choose `text`.
197
198It's important to choose the correct annotation here, because `rustdoc` uses it
199in an interesting way: It can be used to actually test your examples, so that
200they don't get out of date. If you have some C code but `rustdoc` thinks it's
201Rust because you left off the annotation, `rustdoc` will complain when trying to
202generate the documentation.
203
204## Documentation as tests
205
206Let'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
215You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
216automatically add a main() wrapper around your code, and in the right place.
217For 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 228This will end up testing:
85aaf69f 229
62682a34 230```rust
c34b1796
AL
231fn main() {
232 use std::rc::Rc;
233 let five = Rc::new(5);
234}
235```
236
237Here's the full algorithm rustdoc uses to postprocess examples:
238
2391. Any leading `#![foo]` attributes are left intact as crate attributes.
2402. 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.
2443. If the example does not contain `extern crate`, then `extern crate
245 <mycrate>;` is inserted.
2462. 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
249Sometimes, this isn't enough, though. For example, all of these code samples
250with `///` 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 257looks different than the output:
85aaf69f 258
62682a34 259```rust
c34b1796
AL
260/// Some documentation.
261# fn foo() {}
262```
263
264Yes, that's right: you can add lines that start with `# `, and they will
265be hidden from the output, but will be used when compiling your code. You
266can use this to your advantage. In this case, documentation comments need
267to apply to some kind of function, so if I want to show you just a
268documentation comment, I need to add a little function definition below
269it. At the same time, it's just there to satisfy the compiler, so hiding
270it makes the example more clear. You can use this technique to explain
271longer examples in detail, while still preserving the testability of your
272documentation. For example, this code:
273
62682a34 274```rust
c34b1796
AL
275let x = 5;
276let y = 6;
277println!("{}", x + y);
278```
279
280Here's an explanation, rendered:
85aaf69f 281
c34b1796 282First, we set `x` to five:
85aaf69f 283
62682a34 284```rust
c34b1796
AL
285let x = 5;
286# let y = 6;
287# println!("{}", x + y);
288```
289
290Next, we set `y` to six:
85aaf69f 291
62682a34 292```rust
c34b1796
AL
293# let x = 5;
294let y = 6;
295# println!("{}", x + y);
296```
85aaf69f 297
c34b1796 298Finally, we print the sum of `x` and `y`:
85aaf69f 299
62682a34 300```rust
c34b1796
AL
301# let x = 5;
302# let y = 6;
303println!("{}", x + y);
304```
305
306Here'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
332By repeating all parts of the example, you can ensure that your example still
333compiles, while only showing the parts that are relevant to that part of your
334explanation.
335
336### Documenting macros
337
338Here’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]
359macro_rules! panic_unless {
360 ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
361}
362# fn main() {}
363```
364
365You’ll note three things: we need to add our own `extern crate` line, so that
366we 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
368things, so they don’t show up in the output.
369
370### Running documentation tests
371
372To run the tests, either
373
374```bash
375$ rustdoc --test path/to/my/crate/root.rs
376# or
377$ cargo test
378```
379
c1a9b12d 380That's right, `cargo test` tests embedded documentation too. However,
bd371182
AL
381`cargo test` will not test binary crates, only library ones. This is
382due to the way `rustdoc` works: it links against the library to be tested,
383but with a binary, there’s nothing to link to.
c34b1796
AL
384
385There are a few more annotations that are useful to help `rustdoc` do the right
386thing 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
395The `ignore` directive tells Rust to ignore your code. This is almost never
396what you want, as it's the most generic. Instead, consider annotating it
397with `text` if it's not code, or using `#`s to get a working example that
398only 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
408not 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
419The `no_run` attribute will compile your code, but not run it. This is
420important for examples such as "Here's how to start up a network service,"
421which you would want to make sure compile, but might run in an infinite loop!
422
423### Documenting modules
424
425Rust 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
428mod foo {
429 //! This is documentation for the `foo` module.
430 //!
431 //! # Examples
432
433 // ...
85aaf69f
SL
434}
435```
436
c34b1796
AL
437This is where you'll see `//!` used most often: for module documentation. If
438you 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
448Check out [RFC 505][rfc505] for full conventions around the style and format of
449documentation.
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
455All of this behavior works in non-Rust source files too. Because comments
456are written in Markdown, they're often `.md` files.
457
458When you write documentation in Markdown files, you don't need to prefix
459the 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 472is just
85aaf69f 473
c34b1796
AL
474~~~markdown
475# Examples
85aaf69f 476
c34b1796
AL
477```
478use std::rc::Rc;
85aaf69f 479
c34b1796
AL
480let five = Rc::new(5);
481```
85aaf69f
SL
482~~~
483
c34b1796
AL
484when it's in a Markdown file. There is one wrinkle though: Markdown files need
485to have a title like this:
85aaf69f 486
c34b1796
AL
487```markdown
488% The title
85aaf69f 489
c34b1796
AL
490This is the example documentation.
491```
85aaf69f 492
c34b1796 493This `%` line needs to be the very first line of the file.
85aaf69f 494
c34b1796 495## `doc` attributes
85aaf69f 496
c34b1796
AL
497At 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
507are the same, as are these:
508
62682a34 509```rust
c34b1796
AL
510//! this
511
512#![doc="/// this"]
513```
85aaf69f 514
c34b1796
AL
515You won't often see this attribute used for writing documentation, but it
516can 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
523extern crate foo;
524
525pub use foo::bar;
526```
527
c34b1796
AL
528This will create documentation for bar both inside the documentation for the
529crate `foo`, as well as the documentation for your crate. It will use the same
530documentation in both places.
85aaf69f 531
c34b1796 532This behavior can be suppressed with `no_inline`:
85aaf69f 533
c34b1796 534```ignore
85aaf69f
SL
535extern crate foo;
536
537#[doc(no_inline)]
538pub use foo::bar;
539```
c34b1796
AL
540
541### Controlling HTML
542
543You 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
552This 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
566The Markdown in documentation comments is placed without processing into
567the final webpage. Be careful with literal HTML:
568
569```rust
570/// <script>alert(document.cookie)</script>
571# fn foo() {}
572```