Documentation

Doc Comments (triple-slash and bang)

Rust provides two placement styles for documentation comments: outer doc comments (///), which document the item that immediately follows them, and inner doc comments (//!), which document the enclosing crate or module that contains them.

src/lib.rs
+-------------------------------------------------------------------+
| //! # My Networking Crate          <-- INNER (`//!`):             |
| //! High-level overview of the         Documents the enclosing    |
| //! entire crate.                      `lib.rs` crate root!       |
|                                                                   |
| /// A TCP endpoint configuration.  <-- OUTER (`///`):             |
| /// Holds host and port settings.      Documents `struct Endpoint`|
| pub struct Endpoint {                  immediately below it!      |
|     /// Hostname or IP literal.    <-- OUTER (`///`):             |
|     pub host: String,                  Documents field `host`     |
|     /// TCP port number.                                          |
|     pub port: u16,                                                |
| }                                                                 |
+-------------------------------------------------------------------+

Comparing /// (Outer) and //! (Inner)

Syntax Placement Typical Use Cases
/// Placed above the target item Functions (fn), structs, struct fields, enums, enum variants, traits, methods, constants, macros, and pub mod foo; declarations.
//! Placed inside the top of a file or mod { ... } block Crate root (src/lib.rs), module files (src/network.rs or src/network/mod.rs), providing high-level architecture guides and crate-wide examples.

Documenting Modules, Structs, Fields, and Enums Together

In rustdoc output, the first paragraph of any /// or //! comment is rendered as the short summary sentence in module index tables. Keep the opening paragraph to a single concise sentence before adding a blank /// line and detailed paragraphs.

//! Arithmetic and bounded counter primitives.
//!
//! This module provides saturating counters that never wrap around.

/// A counter bounded by an inclusive maximum value.
///
/// Once the counter reaches `max`, subsequent increments saturate at `max`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BoundedCounter {
    /// Current value of the counter (`0 <= current <= max`).
    pub current: u32,
    /// Maximum allowed value for `current`.
    pub max: u32,
}

/// Possible outcomes of a counter step operation.
#[derive(Debug, PartialEq, Eq)]
pub enum StepOutcome {
    /// The counter advanced by 1 to the contained value.
    Advanced(u32),
    /// The counter was already at its maximum bound.
    Saturated,
}

impl BoundedCounter {
    /// Creates a new `BoundedCounter` initialized to `0` with upper bound `max`.
    pub const fn new(max: u32) -> Self {
        Self { current: 0, max }
    }

    /// Advances the counter by `1` unless it has already reached `self.max`.
    pub fn step(&mut self) -> StepOutcome {
        if self.current < self.max {
            self.current += 1;
            StepOutcome::Advanced(self.current)
        } else {
            StepOutcome::Saturated
        }
    }
}

fn main() {
    let mut counter = BoundedCounter::new(1);
    println!("First step:  {:?}", counter.step());
    println!("Second step: {:?}", counter.step());
}
First step:  Advanced(1)
Second step: Saturated

Avoiding Accidental Mixing of /// and //!

A common mistake when writing module-level documentation at the top of src/lib.rs is typing /// instead of //!. If you write /// Crate overview at the top of src/lib.rs above use std::collections::HashMap;, that comment attaches to the use import (or to the first struct in the file) instead of the crate root! Always use //! at the top of src/lib.rs for crate-level documentation.