📚 Rust Documentation: Your Code’s Story Book
The Big Idea 🎯
Imagine you built an amazing LEGO castle. Now imagine your friend wants to build one too, but they don’t know how your pieces fit together. Documentation is like leaving little sticky notes on your LEGO castle that say “this piece goes here” and “twist this to open the door.”
In Rust, documentation turns your code into a story book that others (and future you!) can read to understand what your code does.
🗺️ What We’ll Learn
graph TD A["📖 Documentation Comments"] --> B["🏷️ Doc Attributes"] B --> C["🛠️ rustdoc Tool"] C --> D["💡 Examples in Docs"] D --> E["📦 Crate-Level Docs"]
1️⃣ Documentation Comments
What Are They?
Documentation comments are special notes you write above your code. Think of them as speech bubbles in a comic book—they tell readers what’s happening!
Two Types of Doc Comments
| Type | Symbol | What It Documents |
|---|---|---|
| Outer doc | /// |
The thing below it |
| Inner doc | //! |
The thing it’s inside |
Example: Outer Doc Comments (///)
/// Adds two numbers together.
///
/// # Example
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
fn add(a: i32, b: i32) -> i32 {
a + b
}
Think of /// like a name tag you stick on top of something. The note describes what’s below it.
Example: Inner Doc Comments (//!)
//! This module handles math operations.
//!
//! Use it for adding, subtracting,
//! and more!
fn add(a: i32, b: i32) -> i32 {
a + b
}
Think of //! like writing your name inside your lunchbox. It describes the container you’re inside.
🧠 Quick Memory Trick
///= Arrow pointing DOWN ↓ (documents thing below)//!= Exclamation inside ! (documents thing I’m inside)
2️⃣ Doc Attributes
What Are Attributes?
Attributes are like instruction stickers you put on your code. They tell Rust’s tools how to behave.
The #[doc] Attribute
Instead of ///, you can use #[doc = "..."]:
#[doc = "Multiplies two numbers."]
fn multiply(a: i32, b: i32) -> i32 {
a * b
}
This does the exact same thing as:
/// Multiplies two numbers.
fn multiply(a: i32, b: i32) -> i32 {
a * b
}
Why Use Attributes?
Sometimes you need special powers:
#[doc(hidden)]
fn secret_function() {
// This won't show in docs!
}
#[doc(alias = "times")]
fn multiply(a: i32, b: i32) -> i32 {
a * b
}
// Now searching "times" finds this!
Common Doc Attributes
| Attribute | What It Does |
|---|---|
#[doc(hidden)] |
Hides from documentation |
#[doc(alias = "x")] |
Adds a search nickname |
#[doc(inline)] |
Shows re-exported items inline |
#[doc(no_inline)] |
Keeps re-exports as links |
3️⃣ rustdoc: The Magic Book Maker
What Is rustdoc?
rustdoc is a magical robot that reads all your documentation comments and builds a beautiful website from them!
graph TD A["Your Code + Comments"] --> B["rustdoc Tool"] B --> C["Beautiful HTML Website"]
How to Use It
Generate docs for your project:
cargo doc
Open them in your browser:
cargo doc --open
Build docs for all dependencies too:
cargo doc --document-private-items
What rustdoc Creates
target/doc/
├── your_crate/
│ ├── index.html ← Homepage
│ ├── fn.add.html ← Function page
│ └── struct.User.html← Struct page
└── search-index.js ← Search feature!
🎨 The Output Looks Like…
A professional website with:
- 🔍 Search bar
- 📂 Navigation sidebar
- 📄 Pretty formatted docs
- ✅ Runnable code examples
4️⃣ Examples in Docs
Why Examples Matter
Examples are like recipe pictures in a cookbook. They show people exactly what the result looks like!
Writing Runnable Examples
/// Greets a person by name.
///
/// # Examples
///
/// ```
/// let greeting = greet("Alice");
/// assert_eq!(greeting, "Hello, Alice!");
/// ```
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
The Magic: Doc Tests!
When you run cargo test, Rust actually runs your examples! If they break, your tests fail.
cargo test --doc
Special Example Markers
| Marker | What It Does |
|---|---|
```rust |
Normal runnable example |
```ignore |
Shows code, doesn’t run |
```should_panic |
Expects code to crash |
```no_run |
Compiles but doesn’t run |
```compile_fail |
Should NOT compile |
Example with Markers
/// Opens a file (requires file to exist).
///
/// # Examples
///
/// ```no_run
/// let file = open_file("secret.txt");
/// // Won't run during tests (no file!)
/// ```
fn open_file(path: &str) { /* ... */ }
Hiding Setup Code
Use # to hide boring setup:
/// # Examples
///
/// ```
/// # fn main() -> Result<(), String> {
/// let result = divide(10, 2)?;
/// assert_eq!(result, 5);
/// # Ok(())
/// # }
/// ```
Lines starting with # are invisible in docs but still run!
5️⃣ Crate-Level Documentation
What Is a Crate?
A crate is like a whole box of LEGO pieces. Crate-level docs describe the entire box, not just one piece.
Where to Write It
In your src/lib.rs or src/main.rs, at the very top:
//! # My Amazing Crate 🚀
//!
//! This crate helps you do cool things.
//!
//! ## Quick Start
//!
//! ```rust
//! use my_crate::do_cool_thing;
//! do_cool_thing();
//! ```
//!
//! ## Features
//!
//! - Feature one
//! - Feature two
pub fn do_cool_thing() {
println!("Cool!");
}
The #![doc] Attribute
For special crate-wide settings:
#![doc(html_logo_url = "https://my.com/logo.png")]
#![doc(html_favicon_url = "https://my.com/fav.ico")]
#![doc(html_root_url = "https://docs.rs/my_crate")]
Best Sections for Crate Docs
graph TD A["Crate Docs"] --> B["📌 Overview"] A --> C["🚀 Quick Start"] A --> D["✨ Features"] A --> E["📖 Examples"] A --> F["⚠️ Panics/Errors"]
Real-World Template
//! # Calculator Crate
//!
//! A simple math library for Rust.
//!
//! ## Installation
//!
//! Add to `Cargo.toml`:
//! ```toml
//! [dependencies]
//! calculator = "1.0"
//! ```
//!
//! ## Usage
//!
//! ```
//! use calculator::add;
//! let sum = add(2, 2);
//! assert_eq!(sum, 4);
//! ```
//!
//! ## Modules
//!
//! - [`basic`] - Addition, subtraction
//! - [`advanced`] - Powers, roots
pub mod basic;
pub mod advanced;
🎯 Putting It All Together
Here’s a complete, well-documented mini-crate:
//! # Greeting Library
//!
//! Simple functions to greet people.
//!
//! ## Example
//!
//! ```
//! use greetings::say_hello;
//! say_hello("World");
//! ```
/// Says hello to someone.
///
/// # Arguments
///
/// * `name` - The person to greet
///
/// # Examples
///
/// ```
/// greetings::say_hello("Rust");
/// // Prints: Hello, Rust!
/// ```
pub fn say_hello(name: &str) {
println!("Hello, {}!", name);
}
/// A formal greeting.
///
/// # Examples
///
/// ```
/// let msg = greetings::formal_greeting("Dr. Smith");
/// assert_eq!(msg, "Good day, Dr. Smith.");
/// ```
pub fn formal_greeting(name: &str) -> String {
format!("Good day, {}.", name)
}
🏆 Summary
| Concept | What to Remember |
|---|---|
/// |
Documents the thing BELOW |
//! |
Documents the thing I’m INSIDE |
#[doc(...)] |
Special doc instructions |
cargo doc |
Builds your documentation |
| Doc tests | Examples that run as tests |
| Crate docs | Top-of-file //! comments |
🚀 You Did It!
You now know how to write documentation that:
- ✅ Explains what your code does
- ✅ Shows examples people can trust
- ✅ Generates beautiful websites
- ✅ Tests itself automatically
Your code can now tell its own story! 📖✨
