Rust Documentation

Guide to documenting Rust code with rustdoc.

Documentation Comment Types

flowchart TD
    subgraph "Outer Docs (///)"
        A["/// Documents next item"] --> B[Functions]
        A --> C[Structs]
        A --> D[Enums]
    end

    subgraph "Inner Docs (//!)"
        E["//! Documents containing item"] --> F[Modules]
        E --> G[Crate root]
    end

Outer Documentation (///)

Documents the item that follows:

/// Adds two numbers together.
///
/// This function performs integer addition and returns
/// the sum of the two arguments.
///
/// # Arguments
///
/// * `a` - The first number to add
/// * `b` - The second number to add
///
/// # Returns
///
/// The sum of `a` and `b`
///
/// # Examples
///
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Inner Documentation (//!)

Documents the containing item (module or crate):

// src/lib.rs

//! # My Crate
//!
//! `my_crate` provides utilities for data processing.
//!
//! ## Features
//!
//! - Fast parsing
//! - Type-safe API
//! - Async support
//!
//! ## Quick Start
//!
//! ```
//! use my_crate::process;
//! let result = process("input");
//! ```

Standard Documentation Sections

flowchart LR
    A[Documentation] --> B[Summary<br/>First line]
    A --> C[Description<br/>Details]
    A --> D[Arguments<br/>Parameters]
    A --> E[Returns<br/>Return value]
    A --> F[Examples<br/>Code samples]
    A --> G[Panics<br/>Panic conditions]
    A --> H[Errors<br/>Error conditions]
    A --> I[Safety<br/>Unsafe requirements]

Complete Function Documentation

/// Divides two numbers, returning `None` if the divisor is zero.
///
/// This function performs checked integer division. Unlike the `/`
/// operator, it won't panic on division by zero.
///
/// # Arguments
///
/// * `dividend` - The number to be divided
/// * `divisor` - The number to divide by
///
/// # Returns
///
/// * `Some(quotient)` - The result of the division
/// * `None` - If `divisor` is zero
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use mylib::divide;
///
/// assert_eq!(divide(10, 2), Some(5));
/// assert_eq!(divide(10, 0), None);
/// ```
///
/// # Panics
///
/// This function never panics.
///
/// # Errors
///
/// Returns `None` when dividing by zero.
///
/// # See Also
///
/// * [`add`] - For addition
/// * [`multiply`] - For multiplication
pub fn divide(dividend: i32, divisor: i32) -> Option<i32> {
    if divisor == 0 { None } else { Some(dividend / divisor) }
}

Documenting Types

Structs

/// Configuration options for the application.
///
/// This struct holds all settings needed to configure
/// the application's behavior.
///
/// # Examples
///
/// ```
/// use mylib::Config;
///
/// let config = Config {
///     port: 8080,
///     debug: true,
///     database_url: Some("postgres://localhost/db".into()),
/// };
/// ```
pub struct Config {
    /// The port number to listen on (1-65535).
    pub port: u16,

    /// Enable debug mode for verbose logging.
    pub debug: bool,

    /// Optional database connection URL.
    ///
    /// If `None`, the application runs without database support.
    pub database_url: Option<String>,
}

Enums

/// Represents the current state of a network connection.
///
/// # Examples
///
/// ```
/// use mylib::ConnectionState;
///
/// let state = ConnectionState::Connected { since: 12345 };
/// ```
pub enum ConnectionState {
    /// Connection is active.
    ///
    /// Contains the Unix timestamp when connection was established.
    Connected {
        /// Unix timestamp of connection establishment.
        since: u64,
    },

    /// Connection is not active.
    Disconnected,

    /// Connection is being established.
    Connecting,
}

Traits

/// A trait for types that can be converted to a string.
///
/// # Implementing
///
/// Implementations should return a human-readable representation.
///
/// # Examples
///
/// ```
/// use mylib::Stringify;
///
/// struct Point { x: i32, y: i32 }
///
/// impl Stringify for Point {
///     fn stringify(&self) -> String {
///         format!("({}, {})", self.x, self.y)
///     }
/// }
/// ```
pub trait Stringify {
    /// Converts this value to a string representation.
    fn stringify(&self) -> String;
}

Code Examples in Documentation

Basic Example

/// ```
/// let x = 5;
/// assert_eq!(x * 2, 10);
/// ```

Example Attributes

flowchart TD
    A["```rust"] --> B[Normal - compile and run]
    C["```no_run"] --> D[Compile but don't run]
    E["```ignore"] --> F[Don't compile or run]
    G["```compile_fail"] --> H[Should fail to compile]
    I["```should_panic"] --> J[Should panic when run]
/// Normal example - compiled and executed:
/// ```
/// assert_eq!(2 + 2, 4);
/// ```
///
/// Compiles but doesn't run (e.g., infinite loop):
/// ```no_run
/// loop { /* runs forever */ }
/// ```
///
/// Ignored completely:
/// ```ignore
/// unimplemented_feature();
/// ```
///
/// Should fail to compile:
/// ```compile_fail
/// let x: i32 = "not a number";
/// ```
///
/// Should panic:
/// ```should_panic
/// panic!("expected panic");
/// ```

Hidden Setup Lines

Lines starting with # are compiled but hidden in docs:

/// ```
/// # use std::collections::HashMap;
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut map = HashMap::new();
/// map.insert("key", "value");
/// assert_eq!(map.get("key"), Some(&"value"));
/// # Ok(())
/// # }
/// ```

The rendered documentation shows only:

let mut map = HashMap::new();
map.insert("key", "value");
assert_eq!(map.get("key"), Some(&"value"));

Link to other items in your crate or dependencies:

/// See [`Option::unwrap`] for extracting values.
///
/// Related functions:
/// - [`Self::new`] - Constructor
/// - [`crate::utils::helper`] - Utility function
/// - [`super::parent_fn`] - Parent module function
///
/// Standard library:
/// - [`Vec`] - Dynamic array
/// - [`std::collections::HashMap`] - Hash map
pub fn documented() {}
/// For more information, see the [Rust Book](https://doc.rust-lang.org/book/).
///
/// Reference-style links work too:
///
/// See the [API Guidelines][guidelines] for best practices.
///
/// [guidelines]: https://rust-lang.github.io/api-guidelines/

Module-Level Documentation

// src/parser/mod.rs

//! # Parser Module
//!
//! This module provides parsing functionality for various formats.
//!
//! ## Overview
//!
//! The parser supports:
//! - JSON parsing via [`parse_json`]
//! - TOML parsing via [`parse_toml`]
//!
//! ## Examples
//!
//! ```
//! use mylib::parser::parse_json;
//!
//! let data = parse_json(r#"{"key": "value"}"#)?;
//! # Ok::<(), mylib::Error>(())
//! ```

pub mod json;
pub mod toml;

pub use json::parse_json;
pub use toml::parse_toml;

Documentation Configuration

Cargo.toml for docs.rs

[package.metadata.docs.rs]
# Build with all features enabled
all-features = true

# Or specific features
features = ["full", "async"]

# Target platforms to document
targets = ["x86_64-unknown-linux-gnu"]

# Extra rustdoc arguments
rustdoc-args = ["--cfg", "docsrs"]

Conditional Documentation

Show feature requirements in docs:

#![cfg_attr(docsrs, feature(doc_cfg))]

/// Async version (requires `async` feature).
#[cfg(feature = "async")]
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
pub async fn async_function() {}

Building Documentation

flowchart LR
    A[cargo doc] --> B[Parse source]
    B --> C[Extract doc comments]
    C --> D[Generate HTML]
    D --> E[target/doc/]
    E --> F[Open in browser]
# Build documentation
cargo doc

# Build and open in browser
cargo doc --open

# Include private items
cargo doc --document-private-items

# Only your crate, not dependencies
cargo doc --no-deps

Documentation Lints

Enable warnings for documentation issues:

// At crate root
#![warn(missing_docs)]
#![warn(rustdoc::broken_intra_doc_links)]
#![warn(rustdoc::missing_crate_level_docs)]
# Check docs with Clippy
cargo clippy -- -W clippy::missing_docs_in_private_items

Including README

Use your README.md as crate documentation:

// src/lib.rs
#![doc = include_str!("../README.md")]

Summary

Element Syntax Purpose
Item docs /// Document functions, types
Module docs //! Document modules, crates
Links [Item] Link to other items
Code blocks ` ``` ` Testable examples
Hidden lines # code Setup code in examples

Best Practices

Practice Description
Document all public items Every pub should have docs
First line is summary Keep it concise and clear
Include examples Show how to use the API
Use standard sections Arguments, Returns, Examples, Panics
Test your examples Run cargo test --doc
Link related items Use intra-doc links
Keep docs updated Sync with code changes

Back to top

Rust Programming Guide is not affiliated with the Rust Foundation. Content is provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.