Publicando uma crate no crates.io

1. Preparação da Crate para Publicação

Antes de publicar sua crate no crates.io, é essencial organizar o projeto corretamente. A estrutura padrão gerada por cargo new já é suficiente, mas você deve garantir que todos os metadados no Cargo.toml estejam completos.

[package]
name = "minha-crate"
version = "0.1.0"
edition = "2021"
authors = ["Seu Nome <seu@email.com>"]
description = "Uma crate exemplo para demonstração"
license = "MIT"
repository = "https://github.com/seuusuario/minha-crate"
keywords = ["exemplo", "tutorial", "rust"]
categories = ["algorithms", "data-structures"]

Siga o Semantic Versioning (SemVer): versões iniciais devem começar com 0.1.0. Incremente o patch para correções, minor para novas funcionalidades e major para mudanças incompatíveis.

2. Documentação e README

Um README eficaz deve conter seções de instalação, uso rápido e exemplos práticos. Veja um exemplo:

# minha-crate

Uma biblioteca para processamento de texto em Rust.

## Instalação

Adicione ao seu `Cargo.toml`:

```toml
[dependencies]
minha-crate = "0.1.0"

Uso rápido

use minha_crate::processar_texto;

let resultado = processar_texto("Olá, mundo!");
println!("{}", resultado);

Para documentação da API, use `rustdoc` com comentários `///`:

```rust
/// Processa uma string removendo espaços extras e convertendo para minúsculas.
///
/// # Exemplo
///
/// ```
/// use minha_crate::processar_texto;
///
/// let resultado = processar_texto("  Olá,   Mundo!  ");
/// assert_eq!(resultado, "olá, mundo!");
/// ```
pub fn processar_texto(texto: &str) -> String {
    texto.split_whitespace()
         .collect::<Vec<&str>>()
         .join(" ")
         .to_lowercase()
}

Gere e teste a documentação localmente:

cargo doc --open
cargo test --doc

3. Gerenciamento de Dependências e Features

Escolha dependências cuidadosamente. Dependências públicas afetam seus usuários, enquanto dependências privadas (usadas apenas em testes ou builds) podem ser marcadas como [dev-dependencies].

[dependencies]
serde = { version = "1.0", features = ["derive"] }

[dev-dependencies]
criterion = "0.5"

Para compilação condicional, exponha features no Cargo.toml:

[features]
default = ["std"]
std = []
async = ["tokio"]

No código, use #[cfg(feature = "async")] para habilitar funcionalidades condicionais. Minimize dependências para reduzir tempo de compilação e tamanho final.

4. Testes e Qualidade de Código

Escreva testes unitários, de integração e de documentação:

// tests/integration_test.rs
use minha_crate::processar_texto;

#[test]
fn test_processar_texto_vazio() {
    assert_eq!(processar_texto(""), "");
}

#[test]
fn test_processar_texto_com_espacos() {
    assert_eq!(processar_texto("  Rust  é  incrível  "), "rust é incrível");
}

Use ferramentas de análise:

cargo clippy -- -D warnings
cargo fmt --check
cargo audit

Para projetos críticos, adicione #[deny(unsafe_code)] no lib.rs:

#![deny(unsafe_code)]

5. Configuração da Conta e Token no crates.io

Crie uma conta em crates.io usando autenticação via GitHub. Após o login, gere um token de API:

  1. Acesse Account SettingsAPI Tokens
  2. Crie um novo token com escopo de publicação
  3. Configure localmente:
cargo login <seu-token-aqui>

Verifique seu e-mail no perfil do crates.io para habilitar a publicação.

6. Publicação da Crate

Antes de publicar, verifique os pré-requisitos:

cargo package --list  # Lista arquivos que serão publicados
cargo doc --no-deps   # Verifica se a documentação gera sem erros

Publique a crate:

cargo publish

Erros comuns e soluções:
- Nome duplicado: escolha outro nome ou adicione um prefixo/sufixo
- Dependências não publicadas: publique dependências primeiro ou use [patch]
- Metadados ausentes: preencha description, license e repository

Para publicar novas versões, incremente a versão no Cargo.toml e execute novamente:

# Incrementar versão automaticamente
cargo bump patch  # ou minor, major
cargo publish

7. Pós-Publicação e Manutenção

Verifique sua crate no crates.io. Adicione badges ao README:

[![Crates.io](https://img.shields.io/crates/v/minha-crate)](https://crates.io/crates/minha-crate)
[![Docs.rs](https://docs.rs/minha-crate/badge.svg)](https://docs.rs/minha-crate)

Para remover uma versão problemática:

cargo yank --vers 0.1.0
cargo yank --vers 0.1.0 --undo  # Reverter

Mantenha um changelog seguindo o formato keep-a-changelog:

# Changelog

## [0.2.0] - 2024-01-15
### Added
- Suporte a processamento assíncrono
- Nova função `processar_texto_async`

### Fixed
- Corrigido bug com caracteres especiais

8. Dicas Avançadas e Boas Práticas

Use [package.metadata] para configurações de ferramentas externas:

[package.metadata.docs.rs]
features = ["async"]
rustdoc-args = ["--cfg", "docsrs"]

Publique versões candidatas com pré-lançamento:

version = "0.2.0-alpha.1"

Automatize com CI/CD usando GitHub Actions:

# .github/workflows/publish.yml
name: Publish

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
      - run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}

Lembre-se: uma crate bem documentada, testada e com dependências mínimas tem mais chances de ser adotada pela comunidade Rust.

Referências