rust/src/doc/rustdoc.md
2014-07-02 10:53:30 +02:00

9.0 KiB

% Rust Documentation

rustdoc is the built-in tool for generating documentation. It integrates with the compiler to provide accurate hyperlinking between usage of types and their documentation. Furthermore, by not using a separate parser, it will never reject your valid Rust code.

Creating Documentation

Documenting Rust APIs is quite simple. To document a given item, we have "doc comments":

# #![allow(unused_attribute)]
// the "link" crate attribute is currently required for rustdoc, but normally
// isn't needed.
#![crate_id = "universe"]
#![crate_type="lib"]

//! Tools for dealing with universes (this is a doc comment, and is shown on
//! the crate index page. The ! makes it apply to the parent of the comment,
//! rather than what follows).

# mod workaround_the_outer_function_rustdoc_inserts {
/// Widgets are very common (this is a doc comment, and will show up on
/// Widget's documentation).
pub struct Widget {
	/// All widgets have a purpose (this is a doc comment, and will show up
	/// the field's documentation).
	purpose: String,
	/// Humans are not allowed to understand some widgets
	understandable: bool
}

pub fn recalibrate() {
	//! Recalibrate a pesky universe (this is also a doc comment, like above,
	//! the documentation will be applied to the *parent* item, so
	//! `recalibrate`).
	/* ... */
}
# }

Documentation can also be controlled via the doc attribute on items. This is implicitly done by the compiler when using the above form of doc comments (converting the slash-based comments to #[doc] attributes).

#[doc = "
Calculates the factorial of a number.

Given the input integer `n`, this function will calculate `n!` and return it.
"]
pub fn factorial(n: int) -> int { if n < 2 {1} else {n * factorial(n - 1)} }
# fn main() {}

The doc attribute can also be used to control how rustdoc emits documentation in some cases.

// Rustdoc will inline documentation of a `pub use` into this crate when the
// `pub use` reaches across crates, but this behavior can also be disabled.
#[doc(no_inline)]
pub use std::option::Option;
# fn main() {}

Doc comments are markdown, and are currently parsed with the sundown library. rustdoc does not yet do any fanciness such as referencing other items inline, like javadoc's @see. One exception to this is that the first paragraph will be used as the "summary" of an item in the generated documentation:

/// A whizbang. Does stuff. (this line is the summary)
///
/// Whizbangs are ...
struct Whizbang;

To generate the docs, run rustdoc universe.rs. By default, it generates a directory called doc, with the documentation for universe being in doc/universe/index.html. If you are using other crates with extern crate, rustdoc will even link to them when you use their types, as long as their documentation has already been generated by a previous run of rustdoc, or the crate advertises that its documentation is hosted at a given URL.

The generated output can be controlled with the doc crate attribute, which is how the above advertisement works. An example from the libstd documentation:

#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
      html_root_url = "http://doc.rust-lang.org/")];

The html_root_url is the prefix that rustdoc will apply to any references to that crate's types etc.

rustdoc can also generate JSON, for consumption by other tools, with rustdoc --output-format json, and also consume already-generated JSON with rustdoc --input-format json.

rustdoc also supports personalizing the output from crates' documentation, similar to markdown options.

  • --html-in-header FILE: includes the contents of FILE at the end of the <head>...</head> section.
  • --html-before-content FILE: includes the contents of FILE directly after <body>, before the rendered content (including the search bar).
  • --html-after-content FILE: includes the contents of FILE after all the rendered content.

Using the Documentation

The web pages generated by rustdoc present the same logical hierarchy that one writes a library with. Every kind of item (function, struct, etc) has its own color, and one can always click on a colored type to jump to its documentation. There is a search bar at the top, which is powered by some JavaScript and a statically-generated search index. No special web server is required for the search.

Testing the Documentation

rustdoc has support for testing code examples which appear in the documentation. This is helpful for keeping code examples up to date with the source code.

To test documentation, the --test argument is passed to rustdoc:

rustdoc --test crate.rs

Defining tests

Rust documentation currently uses the markdown format, and rustdoc treats all code blocks as testable-by-default unless they carry a language tag of another language. In order to not run a test over a block of code, the ignore string can be added to the three-backtick form of markdown code block.

```
// This is a testable code block
```

```rust{.example}
// This is rust and also testable
```

```ignore
// This is not a testable code block
```

    // This is a testable code block (4-space indent)

```sh
# this is shell code and not tested
```

You can specify that the test's execution should fail with the should_fail directive.

```should_fail
// This code block is expected to generate a failure when run
```

You can specify that the code block should be compiled but not run with the no_run directive.

```no_run
// This code will be compiled but not executed
```

Lastly, you can specify that a code block be compiled as if --test were passed to the compiler using the test_harness directive.

```test_harness
#[test]
fn foo() {
    fail!("oops! (will run & register as failure)")
}
```

Rustdoc also supplies some extra sugar for helping with some tedious documentation examples. If a line is prefixed with # , then the line will not show up in the HTML documentation, but it will be used when testing the code block (NB. the space after the # is required, so that one can still write things like #[deriving(Eq)]).

```
# /!\ The three following lines are comments, which are usually stripped off by
# the doc-generating tool.  In order to display them anyway in this particular
# case, the character following the leading '#' is not a usual space like in
# these first five lines but a non breakable one.
# // showing 'fib' in this documentation would just be tedious and detracts from
# // what's actually being documented.
# fn fib(n: int) { n + 2 }

spawn(proc() { fib(200); })
```

The documentation online would look like spawn(proc() { fib(200); }), but when testing this code, the fib function will be included (so it can compile).

Running tests (advanced)

Running tests often requires some special configuration to filter tests, find libraries, or try running ignored examples. The testing framework that rustdoc uses is build on crate test, which is also used when you compile crates with rustc's --test flag. Extra arguments can be passed to rustdoc's test harness with the --test-args flag.

# Only run tests containing 'foo' in their name
$ rustdoc --test lib.rs --test-args 'foo'

# See what's possible when running tests
$ rustdoc --test lib.rs --test-args '--help'

When testing a library, code examples will often show how functions are used, and this code often requires use-ing paths from the crate. To accommodate this, rustdoc will implicitly add extern crate <crate>; where <crate> is the name of the crate being tested to the top of each code example. This means that rustdoc must be able to find a compiled version of the library crate being tested. Extra search paths may be added via the -L flag to rustdoc.

Standalone Markdown files

As well as Rust crates, rustdoc supports rendering pure Markdown files into HTML and testing the code snippets from them. A Markdown file is detected by a .md or .markdown extension.

There are 4 options to modify the output that Rustdoc creates.

  • --markdown-css PATH: adds a <link rel="stylesheet"> tag pointing to PATH.
  • --html-in-header FILE: includes the contents of FILE at the end of the <head>...</head> section.
  • --html-before-content FILE: includes the contents of FILE directly after <body>, before the rendered content (including the title).
  • --html-after-content FILE: includes the contents of FILE directly before </body>, after all the rendered content.

All of these can be specified multiple times, and they are output in the order in which they are specified. The first line of the file being rendered must be the title, prefixed with % (e.g. this page has % Rust Documentation on the first line).

Like with a Rust crate, the --test argument will run the code examples to check they compile, and obeys any --test-args flags. The tests are named after the last # heading.