Skip to main content

derive | Rust

  • derive | Rust

#[derive(Debug, Serialize, Deserialize)] no Rust

O que é

No Rust, #[derive(...)] é um atributo que pede ao compilador para criar automaticamente implementações de traits para um tipo (struct ou enum).

Ou seja: em vez de você escrever “na mão” o código necessário para imprimir, converter ou ler dados, o Rust (ou uma macro externa) gera isso por você.

Exemplo:

#[derive(Debug, Serialize, Deserialize)]
struct Pessoa {
nome: String,
idade: u32,
}

O que significa “trait” nesse contexto

Uma trait no Rust é como um “contrato de comportamento”.

Quando você faz:

#[derive(Debug)]

você está dizendo:

“Quero que esse tipo tenha suporte ao comportamento Debug.”

E o Rust cria automaticamente a implementação equivalente a:

impl Debug for Pessoa { ... }

O que cada item do derive faz

Debug

Habilita a impressão do valor para depuração.

Você usa isso quando quer ver o conteúdo do objeto no terminal:

println!("{:?}", pessoa);   // formato compacto
println!("{:#?}", pessoa); // formato bonito/indentado

Sem Debug, o Rust não permite usar {:?} nesse tipo.


Serialize

Vem do crate serde (o padrão do ecossistema Rust para serialização).

Permite transformar sua struct em um formato que pode ser:

  • salvo em arquivo
  • enviado por rede (API)
  • armazenado em banco
  • logado como texto

Na prática, é o que permite converter o tipo para JSON por exemplo:

let json = serde_json::to_string(&pessoa).unwrap();

Resultado típico:

{"nome":"Ana","idade":25}

Deserialize

Também vem do serde.

Faz o caminho inverso:

✅ pega dados (ex: JSON) ✅ interpreta o conteúdo ✅ monta sua struct automaticamente

Exemplo:

let texto = r#"{"nome":"Ana","idade":25}"#;
let pessoa: Pessoa = serde_json::from_str(texto).unwrap();

Por que usar isso no dia a dia

Esse derive é super comum em projetos que:

  • usam API REST (JSON)
  • salvam dados em arquivos
  • trabalham com configurações (YAML/TOML/JSON)
  • precisam logar structs com facilidade

📌 Na prática, ele te economiza bastante código repetitivo.


Dependências necessárias

Para Debug não precisa de nada extra (já faz parte do Rust).

Para Serialize e Deserialize, você precisa do serde no Cargo.toml:

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

O detalhe importante aqui é:

features = ["derive"] isso ativa o suporte ao #[derive(Serialize, Deserialize)].


Exemplo completo (bem direto)

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct Pessoa {
nome: String,
idade: u32,
}

fn main() {
// struct normal
let pessoa = Pessoa {
nome: "Carlos".to_string(),
idade: 30,
};

// struct -> JSON
let json = serde_json::to_string(&pessoa).unwrap();
println!("JSON: {}", json);

// JSON -> struct
let volta: Pessoa = serde_json::from_str(&json).unwrap();
println!("Struct: {:#?}", volta);
}