Doc comment /// dan //! yang kita tulis dua Chapter terakhir kini tersimpan rapi sebagai teks Markdown di dalam source code. Teks itu belum bisa dibaca nyaman: pengguna crate harus membuka file sumber satu per satu, dan Markdown mentah tanpa navigasi cepat melelahkan untuk API berukuran nyata. Kebutuhan sebenarnya adalah halaman HTML dengan sidebar, pencarian, dan tautan antar item — bentuk yang sama dengan dokumentasi crate besar di docs.rs. Rust membawa mesinnya sendiri: alat rustdoc mengumpulkan seluruh doc comment menjadi situs dokumentasi statis, dan Cargo menyediakan pintu cargo doc untuk menjalankannya. Chapter ini menghasilkan dokumentasi HTML dari crate kecil, membedah isinya, lalu memanfaatkan tautan antar item agar dokumentasi bisa ditelusuri tanpa membuka source.

Masalah yang Dipecahkan cargo doc #

Dokumentasi yang tinggal sebagai komentar hanya melayani pembaca yang membuka source code. Begitu crate dikonsumsi sebagai dependensi — lewat crates.io atau path lokal — pembaca tidak lagi punya source di depan matanya, dan membongkar folder ~/.cargo/registry bukan cara belajar yang manusiawi. Situs HTML memecahkan masalah akses itu: satu folder berisi halaman per item, lengkap dengan indeks, pencarian berbasis teks, dan tautan silang. Seluruh docs.io — tepatnya docs.rs — dibangun dari mekanisme yang sama dengan yang akan kita jalankan sekarang, sehingga dokumentasi lokal kita dan dokumentasi ekosistem tampil dan berperilaku seragam.

Mekanisme: rustdoc Membangun Situs Statis #

Perintah cargo doc menjalankan rustdoc untuk crate di workspace kita. Rustdoc mengompilasi crate hingga tahap parsing dan pengumpulan atribut doc, lalu untuk setiap item publik — struct, fungsi, field, modul — merender doc comment Markdown menjadi potongan HTML, menyusun sidebar dan halaman indeksnya, serta menulis hasilnya ke folder target/doc. Tanpa argumen tambahan, cargo doc juga mendokumentasikan seluruh dependensi; opsi --no-deps membatasi pekerjaan hanya pada crate kita sehingga prosesnya jauh lebih cepat. Karena hasilnya file HTML statis, situs dokumentasi bisa dibuka langsung di browser tanpa server, disalin ke hosting statis, atau diunggah sebagai artifact build.

Contoh: Menghasilkan Dokumentasi Crate toner #

Buat proyek library dengan cargo new toner --lib, lalu isi src/lib.rs:

rust
//! Crate `toner` untuk menghitung sisa tinta printer.

/// Menyimpan level tinta dalam persen (0 sampai 100).
pub struct LevelTinta {
    /// Persentase tinta hitam yang tersisa.
    pub hitam: u32,
    /// Persentase tinta warna yang tersisa.
    pub warna: u32,
}

impl LevelTinta {
    /// Membuat [`LevelTinta`] baru dari dua nilai persentase.
    pub fn baru(hitam: u32, warna: u32) -> Self {
        LevelTinta { hitam, warna }
    }

    /// Menampilkan ringkasan sisa tinta dalam satu baris teks.
    pub fn ringkasan(&self) -> String {
        format!("hitam {}% / warna {}%", self.hitam, self.warna)
    }
}

Hasilkan dokumentasinya:

bash
cargo doc --no-deps

Output yang Dihasilkan:

text
 Documenting toner v0.1.0 (/tmp/w5b-rustdoc)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.10s
   Generated /tmp/w5b-rustdoc/target/doc/toner/index.html

Baris Documenting toner v0.1.0 menandai rustdoc mulai bekerja, dan baris Generated .../index.html menunjuk ke pintu masuk situs documentation. Mari kita intip isi folder target/doc yang dihasilkan:

text
crates.js
help.html
search.index
settings.html
src
src-files.js
static.files
toner
trait.impl

Dan isi folder khusus crate kita, target/doc/toner:

text
all.html
index.html
sidebar-items.js
struct.LevelTinta.html

Mari kita bedah apa yang barusan terjadi:

  1. Baris 2 di source (//! Crate toner ...): teks ringkasan crate menjadi isi target/doc/toner/index.html — halaman depan situs documentation crate.
  2. Baris 4-9 (pub struct LevelTinta beserta doc comment field): struct dengan dua field pub menghasilkan file struct.LevelTinta.html. Di halaman itu, doc comment /// Persentase tinta hitam ... tampil sebagai keterangan per field — setiap field pub memang bagian API.
  3. Baris 11 (/// Membuat [LevelTinta] baru ...): potongan [LevelTinta] adalah intra-doc link — rustdoc mengubahnya menjadi tautan HTML ke struct.LevelTinta.html sehingga pembaca bisa melompat langsung ke halaman struct tanpa mencari lewat sidebar.
  4. Baris 14 (/// Menampilkan ringkasan ...): method ringkasan tampil di halaman struct.LevelTinta.html di bagian implementasi, dengan ringkasan paragraf pertama doc comment-nya.
  5. File search.index di target/doc: indeks pencarian yang dipakai kotak search di pojok atas halaman — hasil cargo doc bukan sekadar tumpukan HTML pasif.
  6. Folder static.files dan src: berkas pendukung (CSS, JavaScript, dan render source code) yang dibutuhkan halaman-halaman documentation agar tampilan dan fitur seperti source view berfungsi saat dibuka.

Membuka Dokumentasi di Browser #

Menyusuri file satu per satu lewat file manager itu melelahkan; cargo doc --open membangun dokumentasi lalu langsung membukanya di browser bawaan sistem:

bash
cargo doc --open --no-deps

Output yang Dihasilkan:

text
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
   Generated /tmp/w5b-rustdoc/target/doc/toner/index.html
     Opening /tmp/w5b-rustdoc/target/doc/toner/index.html

Baris Opening ... menunjukkan alat membuka halaman depan documentation. Di halaman tersebut kita akan melihat sidebar berisi daftar item crate, kotak pencarian yang membaca search.index, halaman LevelTinta dengan keterangan field dan method, serta tautan intra-doc yang melompat antar item. Semua fitur ini bekerja offline karena seluruhnya berupa file statis di target/doc.

Tautan Rusak Tidak Lolos Senyap #

Keunggulan intra-doc link adalah rustdoc memverifikasinya. Typo pada nama item memicu warning saat cargo doc, seperti saat kita salah menulis LevelTintaa:

rust
/// Menghitung kebutuhan tinta, lihat [`LevelTintaa`].
pub fn hitung(hari: u32) -> u32 {
    hari * 2
}

Output yang Dihasilkan:

text
 Documenting toner v0.1.0 (/tmp/w5b-rustdoc)
warning: unresolved link to `LevelTintaa`
 --> src/lib.rs:9:41
  |
9 | /// Menghitung kebutuhan tinta, lihat [`LevelTintaa`].
  |                                         ^^^^^^^^^^^ no item named `LevelTintaa` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: `toner` (lib doc) generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s
   Generated /tmp/w5b-rustdoc/target/doc/toner/index.html

Warning unresolved link to menunjuk baris dan kolom persis tautan yang rusak, lengkap dengan catatan bahwa lint rustdoc::broken_intra_doc_links aktif secara bawaan. Perbaikannya satu karakter: kembalikan nama menjadi LevelTinta. Karena tautan diperiksa setiap kali documentation dibangun, refactoring yang mengganti nama item akan langsung ketahuan bila doc comment belum diperbarui — dokumentasi tidak lagi berbohong diam-diam.

Ringkasan #

cargo doc --no-deps menjalankan rustdoc atas doc comment /// dan //!, menghasilkan situs HTML statis di target/doc/<nama-crate>/index.html lengkap dengan sidebar, pencarian, dan render source; --open langsung membukanya di browser. Intra-doc link [`Item`] mengubah penyebutan item menjadi tautan antar halaman dan diverifikasi rustdoc — nama yang salah memicu warning unresolved link. Situs ini menjadi wajah publik crate kita. Tinggal satu keterampilan lagi: menyusun isi doc comment dengan section standar # Examples, # Arguments, dan # Panics supaya documentation tidak hanya tampil rapi tetapi juga terstruktur seragam dengan seluruh ekosistem Rust.