tools (rustdoc)
rustdoc_scrape_examples
This RFC proposes an extension to Rustdoc that automatically scrapes code examples from the project's examples/
directory.
Check out a live demo here: https://willcrichton.net/example-analyzer/warp/trait.Filter.html#method.and
Code examples are an important tool for programmers to understand how a library works. Examples are concrete and contextual: they reference actual values rather than abstract parameters, and they show how to use a function in the context of the code around it.
As a parable of the value of examples, I recently did a small user study where I observed two Rust programmers learning to use the warp library for a basic task. Warp is designed around a generic Filter
abstraction. Both participants found the documentation for Filter
methods to be both imposing and too generic to be useful. For instance, Filter::and
:
The repo authors also included a code example. But neither participant could understand the example because it lacked context.
The participant who was less familiar with Rust struggled to read the documentation and failed to accomplish the task. By contrast, the participant who was more familiar with Rust knew to look in the examples/
directory, where they found a wealth of examples for each function that complemented the documentation. For instance, rejection.rs
shows the usage of and
in combination with map
:
let math = warp::path!("math" / u16);
let div_with_header = math
.and(warp::get())
.and(div_by())
.map(|num: u16, denom: NonZeroU16| {
warp::reply::json(&Math {
op: format!("{} / {}", num, denom),
output: num / denom.get(),
})
});
The goal of this RFC is to bridge the gap between automatically generated documentation and code examples by helping users find relevant examples within Rustdoc.
The scrape-examples
feature of Rustdoc finds examples of code where a particular function is called. For example, if we are documenting Filter::and
, and a file examples/returning.rs
contains a call to and
, then the corresponding Rustdoc documentation looks like this:
After the user-provided documentation in the doc-comment, scrape-examples
inserts a code example (if one exists). The code example shows a window into the source file with the function call highlighted in yellow. The icons in the top-right of the code viewer allow the user to expand the code sample to the full file, or to navigate through other calls in the same file. The link above the example goes to the full listing in Rustdoc's generated src/
directory, similar to other [src]
links.
Additionally, the user can click "More examples" to see every example from the examples/
directory, like this:
To use the scrape-examples
feature, simply add the --scrape-examples
flag like so:
cargo doc --scrape-examples
I have implemented a prototype of the scrape-examples
feature as modifications to rustdoc and cargo. You can check out the draft PRs:
The feature uses the following high-level flow, with some added technical details as necessary.
--scrape-examples
as an argument to cargo doc
.cargo rustdoc --examples
(source).
BuildContext
, Cargo will now recursively invoke rustdoc
on all files matching the --examples
filter. --scrape-examples <output path>
which directs rustdoc to output to a file at the specific location.target/doc/src/example/foo.rs
. These are then linked to during rendering.{function: {file: {locations: [list of spans], other metadata}}}
. See the AllCallLocations
type.--with-examples <path/to/json>
for each generated JSON file. Rustdoc reads the JSON data from disk and stores them in RenderOptions
.The primary use case for this will be on docs.rs. My expectation is that docs.rs would use the --scrape-examples
flag, and all docs hosted there would have the scraped examples.
See "Unresolved questions" for more discussion of the design space.
I have never seen a documentation generator with this exact feature before. There has been some HCI research like Jadeite and Apatite that use code examples to augment generated documentation, e.g. by sorting methods in order of usage. Other research prototypes have clustered code examples to show broad usage patterns, e.g. Examplore.
The main unresolved questions are about the UI: what is the best UI to show the examples inline? My prototype represents my best effort at a draft, but I'm open to suggestions. For example:
To my mind, the main future extensions of this feature are: