Apidog

Plataforma Colaborativa All-in-one para Desenvolvimento de API

Design de API

Documentação de API

Depuração de API

Mock de API

Testes Automatizados de API

Rustdoc: Um Guia para Iniciantes de Documentação de API em Rust

@apidog

@apidog

Updated on abril 3, 2025

A documentação serve como a ponte entre desenvolvedores e os usuários de seu código. No ecossistema Rust, a documentação é elevada a um cidadão de primeira classe através do Rustdoc, uma sofisticada ferramenta de geração de documentação que vem com a distribuição padrão do Rust. Ao contrário das ferramentas de documentação em muitas outras linguagens, o Rustdoc não gera apenas documentação estática—ele cria sites de documentação interativos, testáveis e ricamente formatados que melhoram a descobribilidade e usabilidade do código.

Para desenvolvedores Rust, o Apidog oferece recursos abrangentes de documentação de API para APIs HTTP, com capacidades de teste interativo, formatação visual de respostas e funções colaborativas.

botão

O Apidog foca na documentação de endpoints, formatos de requisição/resposta e especificações HTTP, enquanto o Rustdoc se especializa em documentar código no nível da linguagem—documentando structs, funções, traits e outras construções de programação que compõem um crate Rust. Ambos os sistemas compartilham o objetivo fundamental de tornar sistemas técnicos complexos mais acessíveis através de documentação minuciosa, precisa e utilizável.

botão

O que é Rustdoc?

Rustdoc é uma ferramenta de linha de comando que analisa o código-fonte Rust e comentários de documentação especiais para gerar arquivos HTML, CSS e JavaScript que formam um site de documentação navegável. No núcleo, o Rustdoc opera extraindo comentários de documentação do seu código e os transformando em documentação estruturada.

A operação básica do Rustdoc envolve:

  1. Analisar arquivos de origem Rust para extrair comentários de documentação
  2. Converter esses comentários de Markdown para HTML
  3. Gerar uma estrutura de site pesquisável e navegável
  4. Extrair exemplos de código da documentação e prepará-los para teste
  5. Criar referências cruzadas entre itens
  6. Produzir ativos estáticos para a documentação final

Quando invocado diretamente, o binário Rustdoc aceita um arquivo de código-fonte Rust como entrada:

$ rustdoc src/lib.rs --crate-name meu_crate

Este comando processa o arquivo lib.rs e gera documentação para um diretório doc por padrão. A documentação é estruturada hierarquicamente, refletindo a estrutura do seu código, com páginas separadas para módulos, structs, enums, traits e outras construções Rust.

Nos bastidores, o Rustdoc aproveita as APIs internas do compilador Rust para analisar e entender seu código. Essa integração estreita com o compilador permite que o Rustdoc gere referências cruzadas precisas, documente corretamente assinaturas de tipo e verifique se os exemplos de código realmente compilam e executam corretamente.

Comentários de Documentação no Rust

A documentação em Rust depende de uma sintaxe de comentário especial que difere dos comentários de código normais. Existem dois tipos principais de comentários de documentação:

Comentários de Documentação Externos (///)

Comentários de documentação externos documentam o item que os segue e são denotados por três barras inclinadas:

/// Este é um comentário de documentação para a função abaixo.
/// Pode abranger várias linhas e suporta formatação Markdown.
pub fn funcao_documentada() -> bool {
    true
}

Esses comentários descrevem funções, structs, enums, traits, módulos e outros itens em sua base de código. Eles são chamados de "comentários externos" porque existem fora do item que documentam.

Comentários de Documentação Internos (//!)

Comentários de documentação internos documentam o item em que aparecem e são denotados por //!:

//! Este módulo fornece utilitários para analisar arquivos de configuração.
//!
//! # Exemplos
//!
//! ```
//! let config = meu_crate::config::parse("config.toml");
//! assert!(config.is_ok());
//! ```

pub fn parse(caminho_do_arquivo: &str) -> Result<Config, ParseError> {
    // Implementação aqui
}

Comentários de documentação internos são comumente usados para documentação em nível de módulo ou crate. Quando colocados no início de um arquivo lib.rs, documentam todo o crate e formam a página inicial da documentação gerada.

A diferença técnica entre esses estilos de comentários é sutil, mas importante: /// documenta o que vem depois dele, enquanto //! documenta o que o contém.

Suporte a Markdown no Rustdoc

O Rustdoc usa um analisador Markdown compatível com CommonMark com várias extensões. Isso dá aos autores da documentação acesso a um rico conjunto de opções de formatação:

Formatação Básica

/// # Cabeçalho Nível 1
/// ## Cabeçalho Nível 2
///
/// Parágrafos são separados por linhas em branco.
///
/// *Texto em itálico* e **texto em negrito** são suportados.
///
/// - Listas não ordenadas
/// - Podem ser criadas
/// - Assim
///
/// 1. Listas ordenadas
/// 2. Funcionam também
///
/// `Código inline` é cercado por crases.

Blocos de Código

Blocos de código são particularmente importantes no Rustdoc, pois servem a dois propósitos: exibem exemplos de código na documentação e podem ser extraídos como testes.

/// ```rust
/// // Este é um bloco de código
/// let x = 5;
/// assert_eq!(x, 5);
/// ```

Por padrão, se nenhuma linguagem for especificada após as três crases de abertura, o Rustdoc assume que o bloco de código contém código Rust. No entanto, você pode especificar outras linguagens para destaque de sintaxe:

/// ```json
/// {
///     "name": "exemplo",
///     "version": "1.0.0"
/// }
/// ```

Extensões do Rustdoc

O Rustdoc estende o CommonMark com várias características adicionais:

Texto Sublinhado

/// ~~Texto sublinhado~~ usa til.

Notas de Rodapé

/// Esta declaração precisa de esclarecimento[^1].
///
/// [^1]: Aqui está o esclarecimento.

Tabelas

/// | Cabeçalho1 | Cabeçalho2 |
/// |---------|---------|
/// | célula1   | célula2   |
/// | célula3   | célula4   |

Listas de Tarefas

/// - [x] Tarefa concluída
/// - [ ] Tarefa incompleta

Pontuação Inteligente

O Rustdoc converte automaticamente sequências de pontuação ASCII em seus equivalentes Unicode:

  • -- se torna um traço en (–)
  • --- se torna um traço em (—)
  • ... se torna reticências (…)
  • As aspas retas se tornam aspas curvas

Interface de Linha de Comando Rustdoc Detalhada

O Rustdoc oferece um conjunto abrangente de opções de linha de comando para personalizar a geração de documentação:

$ rustdoc --help

Algumas das opções mais tecnicamente significativas incluem:

  • --document-private-items: Por padrão, o Rustdoc só documenta itens públicos. Esta flag inclui itens privados na documentação, útil para documentação interna.
  • --test: Executa exemplos de documentação como testes, verificando se compilam e executam como esperado.
  • --test-args: Passa argumentos adicionais para o executor de testes, como --nocapture para mostrar a saída de testes.
  • --edition=EDITION: Especifica a edição Rust para analisar e executar o código (2015, 2018, 2021, 2024).
  • --target=TARGET: Gera documentação para a plataforma alvo especificada.
  • --crate-type=TYPE: Especifica o tipo de crate para testes (bin, lib, rlib, dylib, cdylib, staticlib, proc-macro).
  • -L FLAG=PATH: Adiciona um diretório ao caminho de busca de bibliotecas, crucial para resolver dependências em testes.
  • --cfg=SPEC: Passa uma flag --cfg para o compilador, permitindo a compilação condicional no código da documentação.
  • --extern NAME=PATH: Especifica o local de um crate externo, permitindo que testes referenciem dependências externas.

Para um projeto com dependências externas, uma invocação típica do Rustdoc pode parecer com:

$ rustdoc src/lib.rs --crate-name exemplo_crate \
  --edition=2021 \
  -L dependency=target/debug/deps \
  --extern serde=target/debug/deps/libserde-abcd1234.rlib \
  --extern tokio=target/debug/deps/libtokio-efgh5678.rlib

Felizmente, o Cargo automatiza esse processo complexo com um comando simples:

$ cargo doc --document-private-items

Integração com Cargo

O Cargo fornece uma interface simplificada para trabalhar com Rustdoc através do comando cargo doc. Internamente, o Cargo chama o Rustdoc com os parâmetros apropriados:

$ cargo doc --verbose

Executar este comando exibirá a invocação real do Rustdoc, revelando como o Cargo configura caminhos para dependências e diretórios de saída.

A funcionalidade principal inclui:

  • cargo doc: Gera documentação para o crate atual e suas dependências
  • cargo doc --no-deps: Gera documentação apenas para o crate atual
  • cargo doc --open: Gera documentação e a abre em um navegador da web
  • cargo doc --document-private-items: Inclui itens privados na documentação
  • cargo test --doc: Executa testes de documentação

O Cargo determina inteligentemente o nome do crate a partir do seu arquivo Cargo.toml, configura corretamente a estrutura do diretório de saída sob target/doc/ e garante que todas as dependências estejam devidamente vinculadas.

Estrutura e Organização da Documentação

Documentação em Nível de Crate

A documentação em nível de crate serve como a página de aterrissagem para sua biblioteca e deve fornecer uma visão geral abrangente. Isso é escrito como documentação interna (//!) no topo do arquivo lib.rs:

//! # Minha Biblioteca Avançada de Criptografia
//!
//! Este crate fornece primitivos criptográficos com foco em:
//!
//! - **Desempenho**: Implementações otimizadas para CPUs modernas
//! - **Segurança**: Algoritmos verificados formalmente
//! - **Usabilidade**: APIs de alto nível e difíceis de usar erroneamente
//!
//! ## Início Rápido
//!
//! ```rust
//! use crypto_lib::{Cipher, Mode};
//!
//! let key = crypto_lib::generate_key(256);
//! let cipher = Cipher::new(&key, Mode::GCM);
//!
//! let plaintext = b"Mensagem secreta";
//! let ciphertext = cipher.encrypt(plaintext);
//! ```
//!
//! ## Recursos
//!
//! O crate suporta os seguintes algoritmos:
//!
//! - AES (128, 192, 256)
//! - ChaCha20
//! - Poly1305
//! - HMAC
//! - PBKDF2

A documentação eficaz em nível de crate geralmente inclui:

  1. Uma descrição concisa, em uma frase, do propósito do crate
  2. Explicação detalhada de conceitos e recursos-chave
  3. Exemplos de início rápido mostrando uso básico
  4. Visão geral da arquitetura para bibliotecas mais complexas
  5. Flags de recurso e opções de configuração
  6. Informações de compatibilidade
  7. Características de desempenho

Documentação em Nível de Módulo

Os módulos atuam como unidades organizacionais no Rust e devem ter sua própria documentação que explica seu propósito e conteúdos:

pub mod simetrico {
    //! Algoritmos de criptografia simétrica.
    //!
    //! Este módulo fornece implementações de cifras de bloco e fluxo,
    //! algoritmos de criptografia autenticada e utilitários relacionados.
    //!
    //! # Considerações de Segurança
    //!
    //! Todas as implementações foram auditadas por [Empresa de Segurança]
    //! e verificadas formalmente usando [Ferramenta de Verificação].

    /// Implementação de cifra de bloco AES com suporte para chaves de 128, 192 e 256 bits.
    pub struct Aes {
        // Campos aqui
    }

    // Mais itens...
}

Documentação em Nível de Item

Itens individuais como structs, funções e traits devem ter uma documentação focada que explica seu propósito, uso e quaisquer considerações especiais:

/// Um gerador de números aleatórios criptograficamente seguro.
///
/// Este CSPRNG usa a fonte de entropia do sistema para gerar
/// bytes aleatórios adequados para operações criptográficas.
///
/// # Exemplos
///
/// ```
/// use crypto_lib::CSPRNG;
///
/// let mut rng = CSPRNG::new();
/// let random_bytes = rng.generate_bytes(32);
/// ```
///
/// # Segurança
///
/// No Linux, isso usa getrandom(2) quando disponível, voltando para /dev/urandom.
/// No Windows, usa BCryptGenRandom.
/// No macOS, usa SecRandomCopyBytes.
pub struct CSPRNG {
    // Detalhes de implementação
}

impl CSPRNG {
    /// Cria um novo gerador de números aleatórios criptograficamente seguros.
    ///
    /// # Panics
    ///
    /// Panica se a fonte de entropia do sistema não estiver disponível.
    ///
    /// # Exemplos
    ///
    /// ```
    /// let rng = crypto_lib::CSPRNG::new();
    /// ```
    pub fn new() -> Self {
        // Implementação
    }

    /// Gera o número especificado de bytes aleatórios.
    ///
    /// # Argumentos
    ///
    /// * `len` - O número de bytes aleatórios a serem gerados
    ///
    /// # Retorna
    ///
    /// Um vetor contendo `len` bytes aleatórios criptograficamente seguros.
    ///
    /// # Exemplos
    ///
    /// ```
    /// use crypto_lib::CSPRNG;
    ///
    /// let mut rng = CSPRNG::new();
    /// let key_material = rng.generate_bytes(32);
    /// assert_eq!(key_material.len(), 32);
    /// ```
    pub fn generate_bytes(&mut self, len: usize) -> Vec<u8> {
        // Implementação
    }
}

Testes de Documentação em Detalhe

Uma das características mais poderosas do Rustdoc é sua capacidade de executar exemplos de código como testes. Isso garante que:

  1. Os exemplos em sua documentação realmente compilam
  2. Os exemplos produzem os resultados esperados
  3. Os exemplos permanecem atualizados conforme sua API evolui

Quando você inclui um bloco de código Rust em sua documentação, o Rustdoc o extrai e cria um suporte de teste ao redor dele:

/// Adiciona dois números.
///
/// # Exemplos
///
/// ```
/// let result = meu_crate::add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Nos bastidores, o Rustdoc transforma isso em um arquivo de teste independente semelhante a:

extern crate meu_crate;

fn main() {
    let result = meu_crate::add(2, 3);
    assert_eq!(result, 5);
}

Este arquivo é então compilado e executado. Se o programa compilar e executar sem pânico, o teste passa.

Pré-processamento de Teste

Antes de executar o teste, o Rustdoc aplica várias transformações para tornar exemplos simples mais ergonômicos:

  1. Lint comuns como unused_variables e dead_code são permitidos
  2. Se o exemplo não contiver extern crate e #![doc(test(no_crate_inject))] não foi especificado, extern crate <meucrate>; é inserido
  3. Se o exemplo não contiver fn main, o código é envolto em fn main() { ... }

Essas transformações permitem que você se concentre nas partes importantes do seu exemplo sem código de configuração.

Controlando o Comportamento do Teste

O Rustdoc fornece vários atributos para controlar como os testes são executados:

  • ignore: O código não é testado
  • should_panic: O código deve compilar, mas panicar quando executado
  • compile_fail: O código não deve compilar
  • no_run: O código é compilado, mas não executado
  • edition2015, edition2018, edition2021: Execute o código com uma edição Rust específica

Exemplos:

/// ```ignore
/// // Este código não é testado
/// let x = function_that_doesnt_exist();
/// ```
///
/// ```should_panic
/// // Este código deve panicar
/// panic!("Este exemplo demonstra um pânico");
/// ```
///
/// ```compile_fail
/// // Este código não deve compilar
/// let x: i32 = "isso não deve compilar";
/// ```
///
/// ```no_run
/// // Este código compila, mas não é executado
/// loop {
///     println!("Isso rodaria para sempre!");
/// }
/// ```
///
/// ```edition2021
/// // Este código usa recursos do Rust 2021
/// let result = try {
///     "10".parse::<i32>()?
/// };
/// ```

Usando ? em Testes de Documentação

Como exemplos de documentação estão envolvidos em uma função main() que retorna (), usar o operador ? requer um tratamento especial. Existem duas abordagens:

  1. Defina explicitamente uma função main que retorna um Result:
/// ```
/// # fn main() -> Result<(), std::io::Error> {
/// let content = std::fs::read_to_string("file.txt")?;
/// println!("Conteúdo do arquivo: {}", content);
/// # Ok(())
/// # }
/// ```

2. Use uma anotação de tipo com Ok(()):

/// ```
/// let content = std::fs::read_to_string("file.txt")?;
/// println!("Conteúdo do arquivo: {}", content);
/// # Ok::<(), std::io::Error>(())
/// ```

Em ambos os casos, o # no início de algumas linhas oculta-as da documentação renderizada, mas as inclui no teste.

Ligação a Itens por Nome

O Rustdoc fornece um poderoso sistema de referência cruzada que permite aos autores de documentação criar links para outros itens na base de código. Este recurso melhora significativamente a navegabilidade da sua documentação.

Para criar um link para outro item, use a sintaxe [nome_do_item]:

/// Usa o tipo [`HashMap`] da biblioteca padrão.
///
/// Também depende da função [`build_map`] definida em outro lugar neste crate.
pub fn process_data() {
    // Implementação
}

/// Constrói um novo [`HashMap`] com valores predefinidos.
pub fn build_map() -> HashMap<String, i32> {
    // Implementação
}

Quando o Rustdoc processa esses links, ele automaticamente os resolve para os itens corretos, criando hyperlinks clicáveis no HTML gerado.

Qualificação de Caminho

Para vinculações mais precisas, especialmente ao lidar com itens que podem ter o mesmo nome em diferentes módulos, você pode usar caminhos totalmente qualificados:

/// Esta função usa [`std::collections::HashMap`] para armazenamento
/// e [`crate::utils::format`] para formatar a saída.
pub fn complex_operation() {
    // Implementação
}

A resolução de caminho segue as regras de visibilidade do Rust, portanto, você só pode vincular a itens que seriam visíveis a partir do escopo atual.

Alvos de Ligação

Você pode vincular a vários tipos de itens:

/// Liga a uma struct: [`MyStruct`]
/// Liga a um enum: [`Option`]
/// Liga a um trait: [`Iterator`]
/// Liga a uma função: [`process_data`]
/// Liga a um método: [`MyStruct::new`]
/// Liga a um módulo: [`crate::utils`]
/// Liga a uma constante: [`MAX_SIZE`]
/// Liga a um alias de tipo: [`Result`]

Esse sistema abrangente de vinculação permite que autores de documentação criem uma rica teia de documentação interconectada que ajuda os usuários a navegar em APIs complexas.

Recursos Avançados de Documentação

O #[doc] Atributo

O atributo #[doc] fornece controle avançado sobre a geração de documentação:

// Equivalente a usar comentários /// 
#[doc = "Esta é a documentação do item abaixo."]
pub struct DocumentedStruct;

// Ocultar um item da documentação
#[doc(hidden)]
pub struct InternalStruct;

// Adicionar aliases de pesquisa
#[doc(alias = "conexão")]
#[doc(alias = "socket")]
pub struct NetworkStream;

Para documentação condicional baseada em flags de recurso:

/// Esta função faz coisas incríveis.
#[doc = "Explicação básica da capacidade."]
#[cfg_attr(feature = "avançado", doc = "Também suporta modo avançado quando o recurso 'avançado' está habilitado.")]
pub fn do_things() {
    // Implementação
}

Padrões de Inclusão de Documentação

Para reutilização de conteúdo em toda a documentação:

/// # Segurança
///
#[doc = include_str!("../docs/common_safety_notes.md")]
pub unsafe fn perform_unsafe_operation() {
    // Implementação
}

Isso permite que você mantenha segmentos de documentação comuns em arquivos separados e os inclua onde necessário, reduzindo a duplicação e garantindo consistência.

Exemplos Extraídos

O Rustdoc pode extrair automaticamente exemplos de código dos testes e diretórios de exemplos do seu crate, fornecendo contexto adicional para o uso da API:

$ cargo doc --document-scraped-examples

Esse recurso funciona ao escanear seu crate em busca de uso de itens públicos e extrair esses usos como exemplos. É particularmente valioso para APIs complexas onde exemplos de documentação inline podem ser insuficientes.

Documentação Condicional

Usando atributos cfg, você pode incluir ou excluir condicionalmente a documentação:

#[cfg(target_os = "windows")]
/// Detalhes de implementação específicos do Windows.
pub fn windows_only_function() {
    // Implementação para Windows
}

#[cfg(target_os = "linux")]
/// Detalhes de implementação específicos do Linux.
pub fn linux_only_function() {
    // Implementação para Linux
}

Isso permite que você crie documentação específica de plataforma ou de recurso que apareça apenas quando relevante.

HTML Personalizado em Documentação

Para necessidades especiais de formatação, o Rustdoc permite incorporar HTML diretamente na documentação:

/// <div class="warning">
/// <strong>Atenção:</strong> Esta função realiza I/O e pode bloquear.
/// </div>
pub fn blocking_operation() {
    // Implementação
}

Combinado com CSS personalizado, isso permite formatação rica além do que o Markdown sozinho oferece.

HTML e CSS Personalizados

O Rustdoc permite a personalização da aparência da documentação gerada através de HTML e CSS:

Pré-processamento HTML

Você pode adicionar HTML personalizado ao cabeçalho da documentação:

$ rustdoc src/lib.rs --html-in-header custom-header.html

Isso é útil para adicionar folhas de estilo personalizadas, bibliotecas JavaScript ou meta tags.

Personalização CSS

Para aplicar CSS personalizado à sua documentação:

$ rustdoc src/lib.rs --css custom-styles.css

Seu arquivo CSS pode direcionar a estrutura HTML do Rustdoc para personalizar cores, fontes, layouts e mais:

/* Mude a cor de fundo principal */
body {
    background-color: #f5f5f5;
}

/* Estilo para blocos de aviso */
.warning {
    background-color: #fff3cd;
    border-left: 4px solid #ffc107;
    padding: 0.5rem 1rem;
    margin: 1rem 0;
}

/* Estilo personalizado para blocos de código */
pre {
    background-color: #282c34;
    border-radius: 6px;
    padding: 1rem;
}

Temas de Renderização Personalizados

O Rustdoc suporta vários temas integrados, incluindo Light, Rust, Coal, Navy e Ayu. Você também pode criar temas personalizados:

$ rustdoc src/lib.rs --theme mytheme.css

Melhores Práticas de Documentação

Exatidão Técnica

A documentação deve ser tecnicamente precisa. Especifique o comportamento exato, casos extremos e características de desempenho:

/// Pesquisa por um elemento em um slice ordenado usando busca binária.
///
/// # Complexidade
///
/// Complexidade de tempo: O(log n)
/// Complexidade de espaço: O(1)
///
/// # Panics
///
/// Panica se o slice não estiver ordenado em ordem crescente.
///
/// # Exemplos
///
/// ```
/// let sorted = [1, 2, 3, 4, 5];
/// assert_eq!(meu_crate::binary_search(&sorted, 3), Some(2));
/// assert_eq!(meu_crate::binary_search(&sorted, 6), None);
/// ```
pub fn binary_search<T: Ord>(slice: &[T], value: T) -> Option<usize> {
    // Implementação
}

Documentação Estruturada

Siga uma estrutura consistente para cada tipo de item:

Funções e métodos:

  • Descrição curta
  • Explicações dos parâmetros
  • Descrição do valor de retorno
  • Casos de erro
  • Seção de pânico (se aplicável)
  • Exemplos
  • Características de desempenho
  • Considerações de segurança (para funções unsafe)

Structs e enums:

  • Propósito e descrição em alto nível
  • Explicações de campo/variantes
  • Métodos de construção
  • Operações comuns
  • Exemplos de uso típico

Traits:

  • Contrato e garantias
  • Explicação dos métodos obrigatórios
  • Documentação de métodos fornecidos
  • Orientação sobre implementação
  • Exemplos mostrando implementação e uso

Precisão da Linguagem

Use uma linguagem técnica precisa e evite ambiguidade:

  • Em vez de "rápido", especifique "complexidade de tempo O(log n)"
  • Em vez de "eficiente em memória", especifique "usa espaço de pilha constante"
  • Em vez de "pode falhar", especifique exatamente as condições de erro
  • Em vez de "entradas grandes", especifique limitações concretas

Informações sobre Versionamento

Documente a estabilidade da API e considerações de versionamento:

/// Processa pacotes de rede de acordo com o RFC 1234.
///
/// # Estabilidade
///
/// Esta função é considerada estável desde a versão 0.2.0.
///
/// # Diferenças de Versão
///
/// Antes da versão 0.3.0, esta função truncaria silenciosamente pacotes
/// maiores que 1500 bytes. Agora ela retorna um erro.
pub fn process_packet(packet: &[u8]) -> Result<ProcessedPacket, PacketError> {
    // Implementação
}

Técnicas Avançadas de Teste

Teste em Diferentes Ambientes

Você pode configurar testes de documentação para serem executados com variáveis de ambiente específicas:

/// ```
/// # std::env::set_var("API_KEY", "test_key");
/// let client = meu_crate::Client::new_from_env()?;
/// # Ok::<(), meu_crate::Error>(())
/// ```

Teste com Recursos Externos

Para testes que precisam de recursos externos, use o atributo no_run e explique os requisitos:

/// ```no_run
/// // Este exemplo requer um banco de dados PostgreSQL em localhost:5432
/// // com nome de usuário "teste" e senha "teste"
/// let db = meu_crate::Database::connect(
///     "postgres://teste:teste@localhost:5432/testdb"
/// )?;
/// # Ok::<(), meu_crate::Error>(())
/// ```

Teste de Manipulação de Erros

Mostre como os erros são tratados em sua API:

/// ```
/// use meu_crate::{process_data, DataError};
///
/// // Caso bem-sucedido
/// let result = process_data(&[1, 2, 3]);
/// assert!(result.is_ok());
///
/// // Caso de erro
/// let error_result = process_data(&[]);
/// assert!(matches!(error_result, Err(DataError::EmptyInput)));
/// ```

Internacionalização e Acessibilidade

Documentação em Línguas que Não São Inglesas

Embora o Rustdoc não tenha suporte integrado à internacionalização, você pode fornecer documentação em várias línguas usando flags de recurso:

#[cfg(feature = "docs-en")]
/// Adiciona dois números.
#[cfg(feature = "docs-es")]
/// Suma dos números.
#[cfg(feature = "docs-ja")]
/// 二つの数値を足します。
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Considerações de Acessibilidade

Escreva documentação que seja acessível a usuários com deficiência:

  1. Forneça alternativas de texto para imagens
  2. Use contraste de cor suficiente
  3. Estruture o conteúdo com cabeçalhos adequados
  4. Torne os exemplos de código amigáveis para leitores de tela
/// O diagrama de arquitetura abaixo ilustra os componentes do sistema:
///
/// ![Diagrama de Arquitetura](./images/architecture.png)
/// *Texto alternativo: Um fluxograma mostrando o fluxo de dados de Entrada através de Processamento até Saída,
/// com componentes de Banco de Dados e Cache nos lados*

Conclusão

O Rustdoc se destaca como uma das ferramentas de documentação mais poderosas e abrangentes em qualquer ecossistema de linguagem de programação. Sua integração estreita com o compilador Rust, robustas capacidades de teste e ricas opções de formatação permitem que desenvolvedores criem documentação que não é apenas descritiva, mas também precisa, utilizável e mantida com facilidade.

Aproveitando todas as capacidades do Rustdoc—desde comentários de documentação básicos até recursos avançados como compilação condicional, HTML/CSS personalizados e testes abrangentes—os desenvolvedores Rust podem criar documentação que serve tanto como um recurso de aprendizagem quanto uma referência confiável.

A documentação é um aspecto fundamental do design de API e usabilidade de software. Quando elaborada com cuidado e precisão técnica usando as capacidades do Rustdoc, torna-se um ativo inestimável que reduz a curva de aprendizado, previne erros e promove o uso correto de suas bibliotecas.

À medida que o ecossistema Rust continua a evoluir, o Rustdoc evolui com ele, melhorando constantemente suas capacidades para atender às necessidades de uma base de usuários cada vez mais diversificada e sofisticada. Ao dominar o Rustdoc, você não apenas melhora sua própria base de código, mas também contribui para os altos padrões de documentação que ajudam a fazer da comunidade Rust uma das mais acolhedoras e acessíveis no mundo da programação.

Perguntas Frequentes

1. Como eu posso debugar testes de documentação que estão falhando?

Resposta: Testes de documentação podem ser depurados usando várias técnicas:

Execute testes com mais saída:

cargo test --doc -- --nocapture

Adicione declarações de impressão ao seu teste (elas ficarão ocultas na documentação, mas visíveis durante as execuções do teste):

/// ```
/// let result = meu_crate::complex_function();
/// # println!("Debug: result = {:?}", result);
/// assert!(result.is_ok());
/// ```

Use a flag -test-args para passar opções adicionais:

cargo test --doc -- --test-args=--show-output

Crie uma reprodução independente do seu teste em um arquivo separado para facilitar a depuração.

Se você estiver usando flags de recurso que podem afetar o teste, certifique-se de que elas estejam habilitadas:

cargo test --doc --features=my-feature

2. Como eu documentar o código inseguro corretamente?

Resposta: Documentar código inseguro requer uma atenção especial aos requisitos de segurança:

  1. Inclua sempre uma seção dedicada “Segurança” que declare claramente todas as invariantes que os chamadores devem manter.
  2. Detalhe o comportamento indefinido que pode resultar se os requisitos de segurança não forem atendidos.
  3. Explique por que a função precisa ser insegura e não pode ser implementada com segurança.
  4. Forneça exemplos mostrando tanto o uso correto quanto o incorreto (use compile_fail para este último).

Exemplo:

/// Desreferencia um ponteiro bruto.
///
/// # Segurança
///
/// O chamador deve garantir que:
/// - O ponteiro está devidamente alinhado para o tipo T
/// - O ponteiro aponta para uma instância inicializada de T
/// - O ponteiro é válido para leituras pelo tamanho de T
/// - Nenhuma outra referência para a mesma memória existe enquanto esta função é executada
///
/// Violar qualquer uma dessas condições leva a um comportamento indefinido.
///
/// # Exemplos
///
/// Uso seguro:
/// ```
/// let value = 42;
/// let ptr = &value como *const i32;
/// unsafe {
///     assert_eq!(meu_crate::deref(ptr), 42);
/// }
/// ```
///
/// ```compile_fail
/// // Isso causaria comportamento indefinido:
/// let ptr = 0x1234 como *const i32;
/// unsafe {
///     meu_crate::deref(ptr); // Ponteiro inválido!
/// }
/// ```
pub unsafe fn deref<T>(ptr: *const T) -> T {
    *ptr
}

3. Como eu crio documentação que é condicionalmente compilada com base nas flags de recurso?

Resposta: Você pode usar #[cfg_attr] e outras diretivas de compilação condicional:

/// Esta função sempre tem documentação básica.
#[cfg_attr(feature = "documentos-estendidos", doc = " Ela também tem uma análise de desempenho detalhada quando o recurso 'documentos-estendidos' está habilitado.")]
#[cfg_attr(feature = "exemplos", doc = "
# Exemplos Avançados

#[cfg_attr(feature = "exemplos", doc = "let result = complex_computation(1000);")] #[cfg_attr(feature = "exemplos", doc = "assert!(result < 0.001);")] #[cfg_attr(feature = "exemplos", doc = "```")] pub fn complex_computation(iterations: usize) -> f64 { // Implementação }


Gere documentação com recursos habilitados:
```bash
cargo doc --features="documentos-estendidos exemplos"

Abordagem alternativa para documentação condicional maior:

/// Documentação básica para todas as compilações
#[cfg(not(feature = "full-docs"))]
pub struct ApiClient;

/// Documentação básica para todas as compilações
///
/// # Processo de Autenticação Detalhado
///
/// Ao autenticar, o cliente realiza estas etapas:
/// 1. Validar credenciais
/// 2. Gerar um token seguro
/// 3. Estabelecer