Documentation with rustdoc
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against Rust 1.99.0 and the 2024 edition, checked on 2026-10-06. rustdoc generates HTML documentation from doc comments in your source, the same tool that produces the standard library documentation and every page on docs.rs. Its examples double as tests, so documented code stays correct. Good API documentation is also one of the Rust API Guidelines' checklist items.
Doc comments
-
///documents the item that follows (an outer doc comment); -
//!documents the item that contains it — the crate inlib.rs, or a module at the top of its file (an inner doc comment).
Both are Markdown, and both are sugar for the #[doc = "..."] attribute. The first paragraph is the item’s summary,
shown in module listings and search results, so keep it to one sentence.
//! # shelf-core
//!
//! Domain types for the *shelf* library catalogue: books, ISBNs, loans, and the
//! [`Catalog`] trait with an in-memory implementation.
//!
//! ```
//! use shelf_core::{Catalog, InMemoryCatalog};
//! let catalog = InMemoryCatalog::new();
//! assert!(catalog.is_empty());
//! ```
/// A validated ISBN-13, stored without hyphens.
///
/// Construct one with [`Isbn::parse`]; the type guarantees that every value has
/// 13 digits and a correct check digit.
///
/// # Examples
///
/// ```
/// use shelf_core::Isbn;
///
/// let isbn = Isbn::parse("978-0-441-01359-3")?;
/// assert_eq!(isbn.as_str(), "9780441013593");
/// # Ok::<(), shelf_core::IsbnError>(())
/// ```
pub struct Isbn(String);
Conventional sections
The API Guidelines and the standard library use a small set of # headings consistently:
| Section | What it documents |
|---|---|
|
at least one runnable example — the most valuable part of the docs |
|
for functions returning |
|
the conditions under which the function panics |
|
for |
/// Lends the book with `isbn` to `member`.
///
/// # Errors
///
/// Returns [`CatalogError::NotFound`] if the ISBN is unknown and
/// [`CatalogError::AlreadyLent`] if another member has the book.
///
/// # Panics
///
/// Panics if `member` is empty.
pub fn lend(isbn: &str, member: &str) -> Result<(), CatalogError> {
assert!(!member.is_empty(), "member must not be empty");
if isbn.is_empty() {
return Err(CatalogError::NotFound);
}
Ok(())
}
/// Errors returned by [`lend`].
#[derive(Debug, PartialEq)]
pub enum CatalogError {
/// No book with that ISBN.
NotFound,
/// The book is already on loan.
AlreadyLent,
}
/// Reads `len` bytes starting at `ptr`.
///
/// # Safety
///
/// `ptr` must be valid for reads of `len` bytes and properly aligned, and the memory
/// must not be mutated for the lifetime of the returned slice.
pub unsafe fn bytes_at<'a>(ptr: *const u8, len: usize) -> &'a [u8] {
// SAFETY: the caller guarantees the conditions documented above.
unsafe { std::slice::from_raw_parts(ptr, len) }
}
fn main() {
assert_eq!(lend("", "alice"), Err(CatalogError::NotFound));
let data = [1u8, 2, 3];
// SAFETY: `data` is a live array of 3 bytes.
println!("{:?}", unsafe { bytes_at(data.as_ptr(), 3) });
}
Intra-doc links
Link to other items by their Rust path in square brackets: [Isbn], [`Isbn::parse`] (backticks inside the
brackets render the link as code), [crate::catalog], [Vec::push], [std::io::Error]. rustdoc resolves them like use paths from the current scope and turns them into URLs,
so links survive moves and re-exports. Disambiguate items that share a name with a prefix ([struct@Loan],
[fn@loan], [macro@shelf]), and add custom text with [the catalogue trait](Catalog). Broken links are reported by
the rustdoc::broken_intra_doc_links lint, which warns by default.
The doc attribute
| Attribute | Effect |
|---|---|
|
omit an item from the docs (it stays public: for macro internals, deprecated shims) |
|
extra search terms |
|
show a re-exported item’s full docs at the re-export site, or just a link |
|
use a file as documentation (common for the crate root) |
|
crate-level presentation settings |
|
code compiled only when building documentation — e.g. to document platform-specific items on every platform |
|
show "Available on crate feature json only" badges on docs.rs
(the |
Source: The rustdoc book: The #[doc attribute]
Re-exports
rustdoc documents an item where it is publicly reachable. A pub use of an item from a private module is inlined:
the item appears in the re-exporting module as if defined there. A pub use of something already public elsewhere (for
example from another crate) appears as a re-export link unless you add #[doc(inline)]. This lets a crate like
shelf-core keep its modules private and present a flat API (see
Modules, Crates & Visibility).
Source: The rustdoc book: Re-exports
Documentation tests
Every fenced code block in a doc comment is, by default, a Rust doctest: rustdoc wraps it in fn main, links it against
your crate, compiles it and runs it. Lines starting with +# + are compiled but hidden from the rendered docs — useful for
setup code and for the Ok::<(), E>(()) trick that lets examples use ?. Fence attributes change how a block is treated:
| Fence | Behaviour |
|---|---|
|
compiled and run; must not panic |
|
compiled but not run (network calls, infinite loops, side effects) |
|
must panic when run |
|
must fail to compile — documents what the API prevents |
|
not compiled at all (avoid; prefer |
|
not Rust: not tested |
|
compile with a specific edition |
|
opt out of combined doctests (2024) for this block |
/// Parses a year printed on a title page.
///
/// ```
/// # use doccheck::parse_year; // hidden line: still compiled
/// assert_eq!(parse_year("© 1965"), Some(1965));
/// ```
///
/// Years before printing are rejected:
///
/// ```should_panic
/// # use doccheck::parse_year;
/// parse_year("1066").expect("printed books only");
/// ```
///
/// A year is a number, not a string:
///
/// ```compile_fail
/// let y: u16 = doccheck::parse_year("1965"); // Option<u16> is not u16
/// ```
pub fn parse_year(text: &str) -> Option<u16> {
let digits: String = text.chars().filter(char::is_ascii_digit).collect();
digits.parse().ok().filter(|y| *y >= 1450)
}
cargo test --doc
# Doc-tests doccheck
# running 3 tests
# test src/lib.rs - parse_year (line 3) ... ok
# test src/lib.rs - parse_year (line 10) - should panic ... ok
# test src/lib.rs - parse_year (line 17) - compile fail ... ok
Since the 2024 edition, doctests are merged into one binary per crate where possible (combined doctests), which makes large documentation suites much faster to run; see Testing & Benchmarking.
rustdoc lints and scraped examples
Useful lints, set in code or in the [lints.rustdoc] table of Cargo.toml:
-
missing_docs(arustclint) — every public item must be documented; common in libraries aswarn; -
rustdoc::broken_intra_doc_linksandrustdoc::private_intra_doc_links— link problems; -
rustdoc::missing_crate_level_docs— no//!at the crate root; -
rustdoc::bare_urls— a URL that is not a Markdown link; -
rustdoc::invalid_codeblock_attributes,rustdoc::unescaped_backticks; -
clippy::missing_errors_doc,missing_panics_doc,missing_safety_doc(pedantic) — missing sections.
Scraped examples (cargo doc -Zrustdoc-scrape-examples on nightly, enabled by default on docs.rs for crates that opt
in through [package.metadata.docs.rs]) take real call sites from your examples/ directory and show them under each
function.
Source: The rustdoc book: Lints
cargo doc and docs.rs
cargo doc --open # build docs for your crate and all dependencies, open in a browser
cargo doc --no-deps # only your crate(s)
cargo doc --document-private-items # include private items (for maintainers)
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps # fail CI on broken links and other rustdoc warnings
Source: The Cargo Book: cargo doc
Every crate published to crates.io is built and hosted on https://docs.rs, with all versions kept. Configure the docs.rs
build (features, targets, --cfg docsrs) in [package.metadata.docs.rs]. rustup doc --std opens the standard library
documentation offline.