Introduction: Why Documentation in Rust is Not a Luxury, but a Necessity
\n\nRust is renowned for its memory safety, performance, and strict type system. However, even the most elegant code is useless if no one understands how to use it. Quality documentation is the bridge between your code and its users (including yourself six months from now).
\n\nFortunately, Rust has powerful built-in tools for automatically generating documentation directly from source code. In this article, we'll break down the entire process: from simple comments to creating full-fledged documentation with examples, links, and even mathematical formulas.
\n\n1. Basics: Doc-Comments and rustdoc
\n\nIn Rust, there are two types of comments: regular (// and /* */) and documentation comments (/// and //!). The latter are processed by the rustdoc utility, which generates HTML documentation.
1.1. Outer and Inner Doc-Comments
\n\n- \n
///— outer comment. Written before an item (function, struct, trait) and describes it. \n //!— inner comment. Used to document the module, crate, or file itself. \n
/// Calculates the factorial of a number n.\n///\n/// # Examples\n/// ```\n/// let result = factorial(5);\n/// assert_eq!(result, 120);\n/// ```\npub fn factorial(n: u32) -> u32 {\n (1..=n).product()\n}\n\n//! # My Super Crate\n//!\n//! This crate provides utilities for working with mathematics.\n//! See the [documentation](https://example.com) for more details.\n\n1.2. Running Documentation Generation
\n\nTo generate documentation, run the command:
\n\ncargo doc --open\n\nThis command scans all doc-comments in your project, creates HTML files in the target/doc/ folder, and opens them in your browser. You'll see a page with a list of modules, functions, and structs — just like on docs.rs.
2. Documentation Sections: How to Make It Readable
\n\nSimply writing a comment is not enough. For documentation to be useful, it needs to be structured. rustdoc supports Markdown, so you can use headings, lists, links, and even code blocks.
2.1. Standard Sections
\n\nIt is customary to use the following sections (starting with # ):
- \n
# Examples— one or more usage examples. \n # Panics— cases in which the function panics. \n # Errors— if the function returns aResult, describe possible errors. \n # Safety— mandatory forunsafefunctions. \n # Arguments— description of parameters (though they are often described directly in the text). \n
/// Reads the contents of a file and returns it as a string.\n///\n/// # Arguments\n/// * `path` — the path to the file.\n///\n/// # Errors\n/// Returns `io::Error` if the file does not exist or is not readable.\n///\n/// # Panics\n/// Panics if the path contains a null byte.\n///\n/// # Examples\n/// ```\n/// let content = read_file("hello.txt").unwrap();\n/// println!("{}", content);\n/// ```\npub fn read_file(path: &str) -> Result<String, std::io::Error> {\n std::fs::read_to_string(path)\n}\n\n2.2. Links and Cross-References
\n\nYou can link to other code items. rustdoc will automatically turn them into hyperlinks:
/// Uses the [`factorial`] function to calculate combinations.\n/// See also the [`math::combinatorics`] module.\npub fn combinations(n: u32, k: u32) -> u32 {\n factorial(n) / (factorial(k) * factorial(n - k))\n}\n\nIf you need to reference a