Introduction: Why Documentation in Rust is Not Just a Whim
In the world of systems programming, Rust occupies a special place due to its safety, performance, and strict compiler. However, even the most elegant code is useless if developers do not understand how to use it. Documentation is the bridge between your code and its users. In Rust, this process is not just recommended, but built into the ecosystem at the tool level.
In this article, we will break down how to write documentation for a Rust project from scratch: from basic doc-comments to creating a full-fledged book using mdbook. You will learn how to use rustdoc, Markdown formatting, and tests in documentation to make your project clear and professional.
Basics: Documenting Code with Doc-Comments
Rust offers two types of comments: regular (//) and doc-comments (/// and //!). Doc-comments are automatically processed by the rustdoc tool, which generates HTML documentation. This is the foundation of any Rust project.
Doc-Comments for Public Items
Use /// to document functions, structs, traits, and modules. Example:
/// Computes the factorial of a number n./// /// # Arguments/// * `n` - a non-negative integer./// /// # Returns/// * `u64` - the factorial of the number n./// /// # Examples/// ```/// let result = factorial(5);/// assert_eq!(result, 120);/// ```pub fn factorial(n: u32) -> u64 { (1..=n).product()}Note the sections # Arguments, # Returns, and # Examples. These are standard Markdown headings that improve readability.
Internal Module Documentation
To document the module itself (the file), use //!:
//! Module for mathematical operations.//!//! This module provides functions for computing factorials,//! Fibonacci numbers, and other mathematical algorithms.Advanced Techniques: Tests, Links, and Attributes
One of the strong points of rustdoc is the ability to run code from documentation as tests. This ensures your examples are always up-to-date and working.
Tests in Documentation (doctests)
Any code block inside doc-comments marked as ```rust or simply ``` automatically becomes a test when running cargo test. Example:
/// Adds two numbers.////// ```/// let sum = add(2, 3);/// assert_eq!(sum, 5);/// ```pub fn add(a: i32, b: i32) -> i32 { a + b}To hide lines that should not be in the example (e.g., fn main()), use the # attribute:
/// ```/// # fn main() {/// let x = 42;/// assert_eq!(x, 42);/// # }/// ```Links to Other Items
You can link to other functions, structs, or modules using the [`name`] syntax. Rustdoc will automatically create a hyperlink:
/// Uses the [`factorial`] function to compute combinations.Documentation Attributes
Attributes allow you to control the behavior of rustdoc:
#[doc(hidden)]— hides an item from the documentation.#[doc(alias = "alternative_name")]— adds an alias for search.#[doc(cfg(feature = "some_feature"))]— shows documentation only when the feature is enabled.
Example of using #[doc(alias)]:
#[doc(alias = "hello")]pub fn greet(name: &str) -> String { format!("Hello, {}!", name)}Generation and Publishing: cargo doc and docs.rs
Once the documentation is written, it needs to be generated