---
title: "Plano de Estudos Rust: Nível Júnior (0-6 Meses)"
url: "https://rustlang.com.br/carreira/plano-estudos-junior/"
markdown_url: "https://rustlang.com.br/carreira/plano-estudos-junior.MD"
description: "Roadmap completo para sair do zero e se tornar um desenvolvedor Rust júnior em 6 meses. Mês a mês, com recursos, projetos práticos e checklist de habilidades para conseguir sua primeira vaga."
date: ""
author: ""
---

# Plano de Estudos Rust: Nível Júnior (0-6 Meses)

Roadmap completo para sair do zero e se tornar um desenvolvedor Rust júnior em 6 meses. Mês a mês, com recursos, projetos práticos e checklist de habilidades para conseguir sua primeira vaga.


Aprender Rust pode parecer intimidador no início, mas com um plano estruturado e dedicação consistente, é perfeitamente possível atingir o nível júnior em cerca de seis meses. Este guia foi criado especificamente para quem está começando do zero ou migrando de outra linguagem e quer construir uma base sólida o suficiente para conquistar sua primeira vaga profissional com Rust.

O plano pressupõe uma dedicação média de 1 a 2 horas por dia durante a semana e 3 a 4 horas nos finais de semana. Se você tiver mais disponibilidade, pode acelerar; se tiver menos, estenda o cronograma proporcionalmente. O importante é manter a **consistência**.

## Visão Geral do Roadmap

Aqui está a visão macro dos seis meses de estudo:

| Mês | Foco Principal | Resultado Esperado |
|-----|---------------|-------------------|
| 1 | Fundamentos da linguagem | Escrever programas simples com confiança |
| 2 | Ownership, borrowing e tipos compostos | Entender o modelo de memória do Rust |
| 3 | Tratamento de erros, coleções e traits | Escrever código idiomático e robusto |
| 4 | Módulos, crates, testes e documentação | Estruturar projetos profissionais |
| 5 | Projeto 1 -- Ferramenta CLI completa | Ter um projeto real no portfólio |
| 6 | Projeto 2 -- API Web + Candidaturas | Estar pronto para o mercado |

## Mês 1: Fundamentos do Rust

O primeiro mês é dedicado a absorver os conceitos básicos da linguagem. Não se preocupe em entender tudo profundamente agora. O objetivo é ganhar fluência na sintaxe e nos conceitos fundamentais.

### Semana 1: Ambiente e Primeiros Passos

**Objetivos:**
- Instalar Rust via rustup
- Configurar seu editor (VS Code + rust-analyzer recomendado)
- Entender o ciclo compile-run
- Escrever seu primeiro "Hello, World!"

**Conteúdo para estudar:**
- Capítulos 1 e 2 do "The Rust Book" (O Livro)
- Instalar e configurar rust-analyzer
- Aprender os comandos básicos do cargo: `new`, `build`, `run`, `check`

```rust
fn main() {
    println!("Olá, mundo Rust!");

    // Experimente modificar e recompilar
    let nome = "Rustacean";
    println!("Bem-vindo(a), {}!", nome);
}
```

**Exercícios práticos:**
- Complete os 10 primeiros exercícios do Rustlings
- Crie 3 programas simples que usem `println!` com formatação
- Explore a documentação com `cargo doc --open`

### Semana 2: Variáveis, Tipos e Funções

**Objetivos:**
- Entender variáveis mutáveis e imutáveis
- Dominar os tipos primitivos (inteiros, floats, bool, char)
- Escrever funções com parâmetros e retorno
- Usar expressões vs. statements

```rust
fn calcular_imc(peso: f64, altura: f64) -> f64 {
    peso / (altura * altura) // expressão - sem ponto-e-vírgula
}

fn classificar_imc(imc: f64) -> &'static str {
    if imc < 18.5 {
        "Abaixo do peso"
    } else if imc < 25.0 {
        "Peso normal"
    } else if imc < 30.0 {
        "Sobrepeso"
    } else {
        "Obesidade"
    }
}

fn main() {
    let peso = 75.0;
    let altura = 1.78;
    let imc = calcular_imc(peso, altura);

    println!("IMC: {:.1} - {}", imc, classificar_imc(imc));
}
```

**Exercícios:**
- Crie uma calculadora que receba operação e operandos
- Implemente uma função que converta Celsius para Fahrenheit
- Escreva um programa que calcule juros compostos

### Semana 3: Controle de Fluxo

**Objetivos:**
- Dominar `if/else`, `loop`, `while`, `for`
- Entender `match` como switch aprimorado
- Usar ranges e iteração sobre coleções

```rust
fn fibonacci(n: u32) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => {
            let mut a: u64 = 0;
            let mut b: u64 = 1;
            for _ in 2..=n {
                let temp = b;
                b = a + b;
                a = temp;
            }
            b
        }
    }
}

fn main() {
    for i in 0..10 {
        println!("fibonacci({}) = {}", i, fibonacci(i));
    }
}
```

**Exercícios:**
- Implemente FizzBuzz usando `match`
- Crie um jogo de adivinhação de números (como no Livro, cap. 2)
- Escreva um programa que encontre números primos até N

### Semana 4: Strings e Dados Básicos

**Objetivos:**
- Entender a diferença entre `String` e `&str`
- Trabalhar com arrays, tuplas e slices
- Praticar formatação de saída

```rust
fn contar_vogais(texto: &str) -> usize {
    texto.chars()
        .filter(|c| "aeiouáéíóúâêôãõ".contains(c.to_lowercase().next().unwrap()))
        .count()
}

fn inverter_palavras(frase: &str) -> String {
    frase.split_whitespace()
        .rev()
        .collect::<Vec<&str>>()
        .join(" ")
}

fn main() {
    let frase = String::from("Rust é incrível para sistemas");
    println!("Vogais: {}", contar_vogais(&frase));
    println!("Invertida: {}", inverter_palavras(&frase));
}
```

### Checklist do Mês 1

- [ ] Ambiente Rust instalado e configurado
- [ ] Capítulos 1-3 do Rust Book lidos
- [ ] 30+ exercícios do Rustlings completados
- [ ] 5+ programas pequenos escritos do zero
- [ ] Confortável com cargo build/run/check

## Mês 2: Ownership, Borrowing e Tipos Compostos

Este é o mês mais importante e possivelmente o mais desafiador. O sistema de ownership é o coração do Rust, e entendê-lo bem agora vai evitar muitas frustrações depois.

### Semana 5: Ownership e Move Semantics

**Objetivos:**
- Entender as 3 regras do ownership
- Compreender move semantics vs. copy
- Saber quando usar `clone()` e quando evitar

```rust
fn main() {
    // Move semantics com String
    let s1 = String::from("Olá");
    let s2 = s1; // s1 foi movido para s2
    // println!("{}", s1); // ERRO: s1 não é mais válido
    println!("{}", s2);

    // Copy semantics com tipos primitivos
    let x = 42;
    let y = x; // x é copiado, não movido
    println!("x = {}, y = {}", x, y); // Funciona!

    // Passando ownership para função
    let nome = String::from("Brasil");
    imprimir(nome); // nome é movido para a função
    // println!("{}", nome); // ERRO: nome foi movido
}

fn imprimir(texto: String) {
    println!("{}", texto);
} // texto é dropped aqui
```

### Semana 6: Borrowing e Referências

**Objetivos:**
- Dominar referências imutáveis (`&T`) e mutáveis (`&mut T`)
- Entender as regras do borrow checker
- Saber resolver erros comuns de borrowing

```rust
fn adicionar_sobrenome(nome: &mut String, sobrenome: &str) {
    nome.push(' ');
    nome.push_str(sobrenome);
}

fn tamanho(texto: &str) -> usize {
    texto.len()
}

fn main() {
    let mut nome = String::from("Ferris");

    // Referência imutável - pode ter várias simultâneas
    let tam = tamanho(&nome);
    println!("Tamanho: {}", tam);

    // Referência mutável - apenas uma por vez
    adicionar_sobrenome(&mut nome, "the Crab");
    println!("Nome completo: {}", nome);
}
```

### Semana 7: Structs e Implementações

**Objetivos:**
- Definir e instanciar structs
- Implementar métodos com `impl`
- Entender struct update syntax e tuple structs

```rust
struct ContaBancaria {
    titular: String,
    saldo: f64,
    ativa: bool,
}

impl ContaBancaria {
    fn nova(titular: String) -> Self {
        ContaBancaria {
            titular,
            saldo: 0.0,
            ativa: true,
        }
    }

    fn depositar(&mut self, valor: f64) -> Result<f64, String> {
        if valor <= 0.0 {
            return Err("Valor deve ser positivo".to_string());
        }
        self.saldo += valor;
        Ok(self.saldo)
    }

    fn sacar(&mut self, valor: f64) -> Result<f64, String> {
        if valor <= 0.0 {
            return Err("Valor deve ser positivo".to_string());
        }
        if valor > self.saldo {
            return Err("Saldo insuficiente".to_string());
        }
        self.saldo -= valor;
        Ok(self.saldo)
    }

    fn extrato(&self) {
        println!("=== Extrato ===");
        println!("Titular: {}", self.titular);
        println!("Saldo: R$ {:.2}", self.saldo);
        println!("Status: {}", if self.ativa { "Ativa" } else { "Inativa" });
    }
}

fn main() {
    let mut conta = ContaBancaria::nova("Maria Silva".to_string());
    conta.depositar(1500.0).unwrap();
    conta.sacar(350.0).unwrap();
    conta.extrato();
}
```

### Semana 8: Enums e Pattern Matching

**Objetivos:**
- Criar enums com dados associados
- Dominar pattern matching com `match`
- Usar `Option<T>` e entender a ausência de null

```rust
enum Forma {
    Circulo(f64),
    Retangulo(f64, f64),
    Triangulo(f64, f64, f64),
}

impl Forma {
    fn area(&self) -> f64 {
        match self {
            Forma::Circulo(raio) => std::f64::consts::PI * raio * raio,
            Forma::Retangulo(largura, altura) => largura * altura,
            Forma::Triangulo(a, b, c) => {
                let s = (a + b + c) / 2.0;
                (s * (s - a) * (s - b) * (s - c)).sqrt()
            }
        }
    }

    fn descricao(&self) -> String {
        match self {
            Forma::Circulo(r) => format!("Círculo com raio {:.1}", r),
            Forma::Retangulo(l, a) => format!("Retângulo {}x{}", l, a),
            Forma::Triangulo(a, b, c) => format!("Triângulo ({}, {}, {})", a, b, c),
        }
    }
}

fn main() {
    let formas = vec![
        Forma::Circulo(5.0),
        Forma::Retangulo(4.0, 6.0),
        Forma::Triangulo(3.0, 4.0, 5.0),
    ];

    for forma in &formas {
        println!("{}: área = {:.2}", forma.descricao(), forma.area());
    }
}
```

### Checklist do Mês 2

- [ ] Capítulos 4-6 do Rust Book lidos
- [ ] Consegue explicar ownership, borrowing e lifetimes para outra pessoa
- [ ] Resolve erros do borrow checker sem desespero
- [ ] Cria structs com métodos e implementações
- [ ] Usa enums com dados associados e pattern matching

## Mês 3: Tratamento de Erros, Coleções e Traits

Agora que você domina a base, é hora de aprender a escrever código robusto e idiomático.

### Semana 9: Tratamento de Erros

**Objetivos:**
- Dominar `Result<T, E>` e `Option<T>`
- Usar o operador `?` para propagação de erros
- Criar tipos de erro personalizados

```rust
use std::fs;
use std::num::ParseIntError;

#[derive(Debug)]
enum AppError {
    ArquivoNaoEncontrado(String),
    ParseErro(ParseIntError),
    ValorInvalido(String),
}

impl std::fmt::Display for AppError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            AppError::ArquivoNaoEncontrado(nome) => {
                write!(f, "Arquivo não encontrado: {}", nome)
            }
            AppError::ParseErro(e) => write!(f, "Erro ao converter: {}", e),
            AppError::ValorInvalido(msg) => write!(f, "Valor inválido: {}", msg),
        }
    }
}

impl From<ParseIntError> for AppError {
    fn from(e: ParseIntError) -> Self {
        AppError::ParseErro(e)
    }
}

fn ler_numero_do_arquivo(caminho: &str) -> Result<i32, AppError> {
    let conteudo = fs::read_to_string(caminho)
        .map_err(|_| AppError::ArquivoNaoEncontrado(caminho.to_string()))?;

    let numero: i32 = conteudo.trim().parse()?;

    if numero < 0 {
        return Err(AppError::ValorInvalido(
            "Número deve ser positivo".to_string(),
        ));
    }

    Ok(numero)
}
```

### Semana 10: Coleções e Iteradores

**Objetivos:**
- Dominar `Vec<T>`, `HashMap<K, V>`, `HashSet<T>`
- Entender o padrão de iteradores (map, filter, fold, collect)
- Usar closures com iteradores

```rust
use std::collections::HashMap;

fn analise_de_texto(texto: &str) -> HashMap<String, usize> {
    let mut contagem: HashMap<String, usize> = HashMap::new();

    for palavra in texto.split_whitespace() {
        let palavra_limpa = palavra
            .to_lowercase()
            .chars()
            .filter(|c| c.is_alphabetic())
            .collect::<String>();

        if !palavra_limpa.is_empty() {
            *contagem.entry(palavra_limpa).or_insert(0) += 1;
        }
    }

    contagem
}

fn top_palavras(contagem: &HashMap<String, usize>, n: usize) -> Vec<(&String, &usize)> {
    let mut pares: Vec<_> = contagem.iter().collect();
    pares.sort_by(|a, b| b.1.cmp(a.1));
    pares.into_iter().take(n).collect()
}

fn main() {
    let texto = "Rust é seguro. Rust é rápido. Rust é incrível. \
                 Aprender Rust vale a pena.";

    let contagem = analise_de_texto(texto);

    println!("Top 5 palavras:");
    for (palavra, freq) in top_palavras(&contagem, 5) {
        println!("  {}: {} vezes", palavra, freq);
    }

    // Exemplo com iteradores encadeados
    let numeros = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let soma_pares: i32 = numeros
        .iter()
        .filter(|&&n| n % 2 == 0)
        .map(|&n| n * n)
        .sum();

    println!("Soma dos quadrados dos pares: {}", soma_pares);
}
```

### Semana 11: Traits

**Objetivos:**
- Definir e implementar traits
- Usar traits como parâmetros (trait bounds)
- Implementar traits da biblioteca padrão (`Display`, `Debug`, `Clone`)

```rust
use std::fmt;

trait Resumivel {
    fn resumo(&self) -> String;

    fn tipo(&self) -> &str {
        "Conteúdo genérico" // implementação padrão
    }
}

struct Artigo {
    titulo: String,
    autor: String,
    conteudo: String,
}

struct Tweet {
    usuario: String,
    texto: String,
    curtidas: u32,
}

impl Resumivel for Artigo {
    fn resumo(&self) -> String {
        format!("{}, por {} - {}...", self.titulo, self.autor, &self.conteudo[..50.min(self.conteudo.len())])
    }

    fn tipo(&self) -> &str {
        "Artigo"
    }
}

impl Resumivel for Tweet {
    fn resumo(&self) -> String {
        format!("@{}: {} ({} curtidas)", self.usuario, self.texto, self.curtidas)
    }

    fn tipo(&self) -> &str {
        "Tweet"
    }
}

impl fmt::Display for Artigo {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "[{}] {} por {}", self.tipo(), self.titulo, self.autor)
    }
}

fn imprimir_resumo(item: &impl Resumivel) {
    println!("[{}] {}", item.tipo(), item.resumo());
}
```

### Semana 12: Lifetimes Básicas

**Objetivos:**
- Entender por que lifetimes existem
- Usar anotações de lifetime básicas
- Entender lifetime elision rules

```rust
// O compilador precisa saber qual referência determina o lifetime do retorno
fn maior<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() {
        s1
    } else {
        s2
    }
}

// Struct com lifetime - garante que a referência vive o suficiente
struct Trecho<'a> {
    texto: &'a str,
    linha: usize,
}

impl<'a> Trecho<'a> {
    fn novo(texto: &'a str, linha: usize) -> Self {
        Trecho { texto, linha }
    }

    fn exibir(&self) {
        println!("Linha {}: {}", self.linha, self.texto);
    }
}

fn main() {
    let texto1 = String::from("Rust");
    let resultado;
    {
        let texto2 = String::from("Ferrugem");
        resultado = maior(&texto1, &texto2);
        println!("Maior: {}", resultado);
    }
    // resultado não pode ser usado aqui se dependesse de texto2
}
```

### Checklist do Mês 3

- [ ] Capítulos 7-10 do Rust Book lidos
- [ ] Sabe criar tipos de erro personalizados
- [ ] Usa iteradores fluentemente (map, filter, collect, etc.)
- [ ] Define e implementa traits própcias
- [ ] Entende lifetimes básicas e sabe anotar quando necessário

## Mês 4: Módulos, Crates, Testes e Documentação

Hora de aprender a estruturar projetos profissionais.

### Semana 13: Módulos e Organização de Código

**Objetivos:**
- Organizar código em módulos e submódulos
- Entender visibilidade (`pub`, `pub(crate)`)
- Criar e usar crates externas

```
meu_projeto/
├── Cargo.toml
├── src/
│   ├── main.rs          // ponto de entrada
│   ├── lib.rs           // biblioteca pública
│   ├── config.rs        // módulo de configuração
│   ├── models/
│   │   ├── mod.rs       // declara submódulos
│   │   ├── usuario.rs
│   │   └── produto.rs
│   └── services/
│       ├── mod.rs
│       ├── auth.rs
│       └── database.rs
└── tests/
    └── integration_test.rs
```

```rust
// src/models/usuario.rs
pub struct Usuario {
    pub nome: String,
    pub email: String,
    senha_hash: String, // privado
}

impl Usuario {
    pub fn novo(nome: String, email: String, senha: &str) -> Self {
        Usuario {
            nome,
            email,
            senha_hash: format!("hash_{}", senha), // simplificado
        }
    }

    pub fn verificar_senha(&self, senha: &str) -> bool {
        self.senha_hash == format!("hash_{}", senha)
    }
}
```

### Semana 14: Testes Unitários e de Integração

**Objetivos:**
- Escrever testes unitários com `#[test]`
- Usar `assert!`, `assert_eq!`, `assert_ne!`
- Criar testes de integração
- Testar código que retorna `Result`

```rust
pub fn dividir(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("Divisão por zero".to_string())
    } else {
        Ok(a / b)
    }
}

pub fn eh_palindromo(texto: &str) -> bool {
    let limpo: String = texto
        .to_lowercase()
        .chars()
        .filter(|c| c.is_alphanumeric())
        .collect();
    let reverso: String = limpo.chars().rev().collect();
    limpo == reverso
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn dividir_numeros_validos() {
        assert_eq!(dividir(10.0, 2.0).unwrap(), 5.0);
    }

    #[test]
    fn dividir_por_zero_retorna_erro() {
        assert!(dividir(10.0, 0.0).is_err());
    }

    #[test]
    fn palindromo_simples() {
        assert!(eh_palindromo("arara"));
        assert!(eh_palindromo("Ana"));
        assert!(!eh_palindromo("rust"));
    }

    #[test]
    fn palindromo_com_espacos() {
        assert!(eh_palindromo("A base do teto desaba"));
    }
}
```

### Semana 15: Documentação e Cargo

**Objetivos:**
- Escrever doc comments (`///` e `//!`)
- Gerar documentação com `cargo doc`
- Configurar `Cargo.toml` corretamente
- Usar features e dependências opcionais

```rust
//! # Minha Biblioteca de Utilidades
//!
//! Esta crate fornece funções utilitárias para manipulação
//! de texto e cálculos matemáticos.

/// Calcula a média de uma sequência de números.
///
/// # Argumentos
///
/// * `numeros` - Um slice de valores f64
///
/// # Retorno
///
/// Retorna `Some(media)` se o slice não estiver vazio,
/// ou `None` caso contrário.
///
/// # Exemplos
///
/// ```
/// let nums = vec![1.0, 2.0, 3.0, 4.0, 5.0];
/// let media = minha_lib::media(&nums);
/// assert_eq!(media, Some(3.0));
/// ```
pub fn media(numeros: &[f64]) -> Option<f64> {
    if numeros.is_empty() {
        return None;
    }
    Some(numeros.iter().sum::<f64>() / numeros.len() as f64)
}
```

### Semana 16: Gerenciamento de Dependências e Ferramentas

**Objetivos:**
- Adicionar e gerenciar dependências no `Cargo.toml`
- Usar `clippy` para linting
- Formatar código com `rustfmt`
- Usar `cargo bench` para benchmarks simples

```toml
[package]
name = "meu-projeto"
version = "0.1.0"
edition = "2021"
authors = ["Seu Nome <email@exemplo.com>"]
description = "Descrição do meu projeto"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1", features = ["full"] }
clap = { version = "4", features = ["derive"] }

[dev-dependencies]
assert_cmd = "2.0"
predicates = "3.0"
```

### Checklist do Mês 4

- [ ] Capítulos 11-14 do Rust Book lidos
- [ ] Sabe organizar projeto em módulos
- [ ] Escreve testes unitários e de integração
- [ ] Documenta código com doc comments
- [ ] Usa clippy e rustfmt regularmente

## Mês 5: Projeto 1 -- Ferramenta CLI Completa

Este mês inteiro é dedicado a construir seu primeiro projeto real. Uma ferramenta de linha de comando é perfeita para o portfólio porque demonstra habilidades práticas sem a complexidade de um framework web.

### Ideia de Projeto: Gerenciador de Tarefas CLI

Construa um gerenciador de tarefas com as seguintes funcionalidades:

**Funcionalidades mínimas:**
- Adicionar tarefas com título e prioridade
- Listar tarefas (todas, pendentes, concluídas)
- Marcar tarefas como concluídas
- Remover tarefas
- Salvar/carregar de um arquivo JSON
- Filtrar por prioridade

**Tecnologias sugeridas:**
- `clap` para parsing de argumentos
- `serde` + `serde_json` para serialização
- `chrono` para datas
- `colored` para output colorido

### Estrutura do Projeto

```
task-manager/
├── Cargo.toml
├── README.md
├── src/
│   ├── main.rs
│   ├── cli.rs       // definição dos comandos
│   ├── task.rs      // modelo de tarefa
│   ├── storage.rs   // persistência em JSON
│   └── display.rs   // formatação de saída
└── tests/
    └── integration.rs
```

### Exemplo de Código Principal

```rust
use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "tarefas")]
#[command(about = "Gerenciador de tarefas no terminal")]
struct Cli {
    #[command(subcommand)]
    comando: Comandos,
}

#[derive(Subcommand)]
enum Comandos {
    /// Adiciona uma nova tarefa
    Adicionar {
        /// Título da tarefa
        titulo: String,
        /// Prioridade (alta, media, baixa)
        #[arg(short, long, default_value = "media")]
        prioridade: String,
    },
    /// Lista todas as tarefas
    Listar {
        /// Filtrar por status (todas, pendentes, concluidas)
        #[arg(short, long, default_value = "todas")]
        filtro: String,
    },
    /// Marca uma tarefa como concluída
    Concluir {
        /// ID da tarefa
        id: usize,
    },
    /// Remove uma tarefa
    Remover {
        /// ID da tarefa
        id: usize,
    },
}
```

### Cronograma do Projeto

| Semana | Atividade |
|--------|-----------|
| 17 | Estrutura do projeto, modelos de dados, CLI básica |
| 18 | Persistência em JSON, CRUD completo |
| 19 | Filtros, formatação bonita, tratamento de erros |
| 20 | Testes, documentação, README, polish final |

### Dicas Importantes

1. **Comece simples**: faça funcionar primeiro, depois melhore
2. **Commits frequentes**: faça commits pequenos e descritivos
3. **Testes desde o início**: não deixe para o final
4. **README completo**: inclua instalação, uso e exemplos
5. **Peça feedback**: compartilhe na comunidade Rust Brasil

## Mês 6: Projeto 2 -- API Web + Preparação para Vagas

O último mês combina a construção de um segundo projeto (web) com a preparação ativa para candidaturas.

### Projeto 2: API REST Simples

Construa uma API REST para um sistema de notas/anotações:

**Funcionalidades:**
- CRUD de notas (criar, listar, buscar, atualizar, deletar)
- Busca por texto
- Tags e categorias
- Paginação

**Tecnologias sugeridas:**
- `axum` como framework web
- `sqlx` com SQLite para persistência
- `serde` para serialização JSON
- `tokio` como runtime async
- `tower-http` para middleware (CORS, logging)

### Exemplo de Endpoint

```rust
use axum::{
    extract::{Path, State},
    http::StatusCode,
    routing::{get, post},
    Json, Router,
};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone)]
struct Nota {
    id: Option<i64>,
    titulo: String,
    conteudo: String,
    tags: Vec<String>,
}

async fn criar_nota(
    State(pool): State<sqlx::SqlitePool>,
    Json(nota): Json<Nota>,
) -> Result<(StatusCode, Json<Nota>), StatusCode> {
    let resultado = sqlx::query_as!(
        Nota,
        "INSERT INTO notas (titulo, conteudo) VALUES (?, ?) RETURNING *",
        nota.titulo,
        nota.conteudo,
    )
    .fetch_one(&pool)
    .await
    .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok((StatusCode::CREATED, Json(resultado)))
}
```

### Preparação para Vagas (Semanas 23-24)

**Currículo:**
- Destaque os dois projetos do portfólio
- Mencione contribuições open source (se tiver)
- Liste as tecnologias Rust que domina
- Inclua link do GitHub com projetos bem documentados

**Onde buscar vagas:**
- LinkedIn (filtrar por "Rust developer")
- Comunidade Rust Brasil (Telegram/Discord)
- Remote OK, We Work Remotely
- Empresas que usam Rust (lista no site oficial)
- Plataformas brasileiras: Gupy, Catho, GeekHunter

**Preparação para entrevistas:**
- Revise ownership, borrowing e lifetimes
- Pratique coding challenges no LeetCode (em Rust)
- Estude perguntas comuns (veja nosso guia de entrevistas)
- Faça mock interviews com amigos da comunidade

## Recursos Recomendados por Fase

### Fase 1 (Meses 1-2): Fundamentos

| Recurso | Tipo | Custo |
|---------|------|-------|
| The Rust Programming Language (O Livro) | Livro online | Gratuito |
| Rustlings | Exercícios interativos | Gratuito |
| Rust by Example | Exemplos práticos | Gratuito |
| Exercism - Rust Track | Exercícios com mentoria | Gratuito |
| "Primeiros Passos com Rust" (YouTube BR) | Vídeo-aulas | Gratuito |

### Fase 2 (Meses 3-4): Intermediário

| Recurso | Tipo | Custo |
|---------|------|-------|
| Programming Rust (O'Reilly) | Livro | Pago |
| Rust in Action | Livro | Pago |
| Crust of Rust (Jon Gjengset) | YouTube | Gratuito |
| Rust Design Patterns | Livro online | Gratuito |
| Exercism - Exercícios avançados | Exercícios | Gratuito |

### Fase 3 (Meses 5-6): Projetos

| Recurso | Tipo | Custo |
|---------|------|-------|
| Zero To Production In Rust | Livro | Pago |
| Documentação do Axum | Docs | Gratuito |
| Documentação do Clap | Docs | Gratuito |
| Awesome Rust (GitHub) | Lista curada | Gratuito |
| Comunidade Rust Brasil | Telegram/Discord | Gratuito |

## Checklist Final: Pronto para Vagas Júnior?

Antes de se candidatar, verifique se você domina estes tópicos:

### Conhecimento Técnico

- [ ] Variáveis, tipos, funções e controle de fluxo
- [ ] Ownership, borrowing e lifetimes (conceitual e prático)
- [ ] Structs, enums e pattern matching
- [ ] Traits e generics básicos
- [ ] Tratamento de erros com Result e Option
- [ ] Coleções (Vec, HashMap, iteradores)
- [ ] Módulos, crates e visibilidade
- [ ] Testes unitários e de integração
- [ ] Documentação de código
- [ ] Uso básico de async/await (para o projeto web)

### Portfólio

- [ ] Pelo menos 2 projetos completos no GitHub
- [ ] Projetos com README bem escrito
- [ ] Código limpo e bem organizado
- [ ] Testes automatizados nos projetos
- [ ] Commits descritivos e organizados

### Habilidades Complementares

- [ ] Git e GitHub fluente
- [ ] Linha de comando confortável
- [ ] Noções de HTTP e REST APIs
- [ ] SQL básico
- [ ] Inglês para leitura técnica (mínimo)

## Dicas Finais de Motivação

1. **Não compare seu progresso** com o de outros. Cada pessoa tem seu ritmo e contexto.

2. **Erros do compilador são seus amigos**. O compilador do Rust é famoso por suas mensagens de erro didáticas. Leia-as com atenção.

3. **A curva de aprendizado é real, mas temporária**. Os primeiros 2 meses são os mais difíceis. Depois disso, a produtividade cresce exponencialmente.

4. **Participe da comunidade desde o dia 1**. Faça perguntas, compartilhe suas conquistas, ajude quem está começando depois de você.

5. **Consistência vence intensidade**. Estudar 1 hora por dia durante 6 meses é melhor que estudar 12 horas por dia durante 2 semanas e desistir.

6. **Celebre cada pequena vitória**. Compilou sem erros? Entendeu lifetimes? Conseguiu usar iteradores? Cada passo conta.

Lembre-se: milhares de pessoas aprenderam Rust partindo do zero. Você também pode. A comunidade Rust é reconhecida mundialmente por ser acolhedora e prestativa. Use isso a seu favor.

Boa jornada, futuro(a) Rustacean!
