No description
Find a file
2026-08-14 07:20:36 +02:00
.woodpecker chore: migrate CI to .woodpecker/{push,branch}.yml 2026-08-14 07:20:36 +02:00
src fix: reorganize lesson 018 content to match enums curriculum 2026-08-14 07:20:36 +02:00
tests fix: reorganize lesson 018 content to match enums curriculum 2026-08-14 07:20:36 +02:00
.gitignore Initial commit 2026-08-14 05:20:03 +00:00
Cargo.lock initial content 2026-08-14 07:20:32 +02:00
Cargo.toml chore: declare MSRV 1.85 (edition 2024) 2026-08-14 07:20:36 +02:00
LICENSE chore: add AGPL-3.0 license and standard .gitignore 2026-08-14 07:20:36 +02:00
README.md fix: reorganize lesson 018 content to match enums curriculum 2026-08-14 07:20:36 +02:00

Lição 18: Estados do Sistema (Enums)

1. Narrativa

Nem todo subsistema do mecha Æther é uma quantidade contínua como energia ou temperatura. O reator vive em um de quatro estados mutuamente exclusivos — Estavel, Sobrecarregado, Esgotado ou Falhando — e o sistema de alertas emite quatro tipos distintos, alguns carregando dados extras. Estados do Sistema ensina o piloto a modelar essas alternativas com enums, o tipo que Rust usa para representar "exatamente um entre vários possíveis".

2. Conceito

Enums ("enumerations") listam as variantes válidas de um tipo. Ao contrário das structs da Lição 17 (que combinam vários campos em UM valor), uma enum representa uma escolha entre vários:

  • Variante unitária: sem dados adicionais — Estavel, Informacao
  • Variante de tupla: com dados posicionais — Aviso(String), Critico(String)
  • Variante de struct: com campos nomeados — Erro { codigo: i32, mensagem: String }
  • Apenas uma variante é válida por vez por valor
  • Consumo com match (exaustivo) e if let (variante única de interesse)
  • Pattern matching avançado (guards, ranges, destructuring composto) é tema da Lição 19
  • Option<T> e Result<T, E> são enums especiais da biblioteca padrão — tema da Lição 20
  • Métodos em enums via impl — tema da Lição 25

3. Requisitos

  • Definir enums combinando variantes unitárias, de tupla e de struct
  • Construir valores escolhendo uma variante (com e sem dados)
  • Consumir enums com match (com destructuring) e if let
  • Distinguir quando usar enum (alternativas mutuamente exclusivas) vs struct (campos que coexistem)

4. Design de Dados

graph LR
    A[enum] --> B[Variante unitária]
    A --> C[Variante de tupla]
    A --> D[Variante de struct]
    B --> E["Estavel / Informacao"]
    C --> F["Aviso(String)"]
    C --> G["Critico(String)"]
    D --> H["Erro { codigo, mensagem }"]
    E --> I[Uma variante por valor]
    F --> I
    G --> I
    H --> I

5. Diagrama de Fluxo

flowchart TD
    A[Modelar alternativas] --> B{Mutuamente exclusivas?}
    B -->|Sim| C[enum]
    B -->|Não, coexistem| D[struct - Lição 17]
    C --> E{Carregam dados?}
    E -->|Sem dados| F[Variante unitária]
    E -->|Um valor| G[Variante de tupla]
    E -->|Vários campos| H[Variante de struct]
    F --> I[Construir variante]
    G --> I
    H --> I
    I --> J[Consumir com match / if let]

6. Funções

Função Descrição
classificar_estado_reator Converte energia em EstadoReator (4 variantes unitárias)
descricao_estado match sobre variantes unitárias → texto
estado_e_operacional match sobre variantes unitárias → bool
criar_aviso Constrói variante de tupla Aviso(String)
criar_erro Constrói variante de struct Erro { codigo, mensagem }
criar_critico Constrói variante de tupla Critico(String)
prioridade_do_alerta match com destructuring sobre dados da variante
contar_criticos if let para filtrar uma única variante

7. Exemplo

enum EstadoReator {
    Estavel,
    Sobrecarregado,
    Esgotado,
    Falhando,
}

enum AlertaSistema {
    Informacao,
    Aviso(String),
    Erro { codigo: i32, mensagem: String },
    Critico(String),
}

fn descricao(estado: EstadoReator) -> &'static str {
    match estado {
        EstadoReator::Estavel => "Reator estável",
        EstadoReator::Sobrecarregado => "Reator sobrecarregado",
        EstadoReator::Esgotado => "Reator esgotado",
        EstadoReator::Falhando => "Reator falhando",
    }
}

fn prioridade(alerta: &AlertaSistema) -> i32 {
    match alerta {
        AlertaSistema::Informacao => 1,
        AlertaSistema::Aviso(_) => 2,
        AlertaSistema::Erro { .. } => 3,
        AlertaSistema::Critico(_) => 4,
    }
}

// Uso:
// let s = descricao(EstadoReator::Estavel);
// assert_eq!(s, "Reator estável");
// let p = prioridade(&AlertaSistema::Critico(String::from("brecha")));
// assert_eq!(p, 4);

8. Missão

  1. Usar o enum EstadoReator fornecido em src/lib.rs (variantes unitárias: Estavel, Sobrecarregado, Esgotado, Falhando) — o tipo já está declarado
  2. Usar o enum AlertaSistema fornecido em src/lib.rs (variante unitária Informacao; variantes de tupla Aviso(String) e Critico(String); variante de struct Erro { codigo: i32, mensagem: String }) — o tipo já está declarado
  3. Implementar classificar_estado_reator retornando a variante correta de EstadoReator segundo o contrato da doc
  4. Implementar descricao_estado e estado_e_operacional com match sobre as variantes unitárias
  5. Implementar criar_aviso, criar_erro e criar_critico construindo cada tipo de variante
  6. Implementar prioridade_do_alerta com match + destructuring (_ e .. para ignorar dados não usados)
  7. Implementar contar_criticos com if let filtrando apenas a variante Critico

9. Como Executar

cargo build
cargo test
cargo clippy -- -D warnings
cargo fmt --check

10. Dicas

  • Apenas uma variante de enum é válida por valor; structs combinam campos que coexistem
  • match em enum é exaustivo: o compilador obriga a cobrir todas as variantes
  • Use _ para ignorar o dado de uma variante de tupla, e .. para ignorar campos de uma variante de struct
  • if let PADRÃO = valor { ... } é útil quando só uma variante interessa; o resto fica de fora
  • #[derive(Debug, Clone, Copy, PartialEq)] funciona com enums — Copy é seguro quando nenhuma variante contém String ou Vec