serde
serde é o framework de serialização em que a maioria dos serviços Rust é construída. Ele separa a forma dos dados (seus tipos) do formato de transmissão (JSON, MessagePack, TOML e mais) através dos traits Serialize e Deserialize.
Receita
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct User {
id: u64,
email: String,
}
fn main() -> serde_json::Result<()> {
let u = User { id: 1, email: "ada@acme.com".into() };
let json = serde_json::to_string(&u)?;
let back: User = serde_json::from_str(&json)?;
assert_eq!(back.email, "ada@acme.com");
Ok(())
}Quando usar isto:
- Qualquer limite de API (HTTP, saída de CLI, arquivos de configuração)
- Linhas de banco de dados mapeadas para structs (com
sqlxousea-orm) - Cargas úteis de eventos em filas ou logs
Exemplo em Funcionamento
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Event {
#[serde(rename = "event_type")]
kind: String,
#[serde(default)]
retries: u32,
}
// Aceita {"event_type":"created"} sem o campo retries
let e: Event = serde_json::from_str(r#"{"event_type":"created"}"#).unwrap();O que isto demonstra:
- Macros
derivecobrem 90% de structs e enums - Atributos de campo controlam a nomenclatura e os padrões
- O mesmo tipo serializa para JSON, YAML ou bincode trocando os crates
Mergulho Profundo
Como Funciona
- Traits -
Serializeescreve um tipo;Deserializeo reconstrói. - Formatos -
serde_json,serde_yaml,toml,bincodesão crates separados. - Derive -
#[derive(Serialize, Deserialize)]gera implementações em tempo de compilação. - Personalizado -
#[serde(with = "module")]ou implementações manuais para formatos incomuns.
Link Cruzado
Para uma cobertura exaustiva, veja a seção dedicada fundamentos do serde: serializadores personalizados, marcação de enum e padrões de zero-cópia.
Armadilhas
- Ponto flutuante em JSON - NaN e inteiros grandes podem não ter round-trip. Correção: use strings ou tipos de ponto fixo para dinheiro.
- Enums sem marcação - ambíguos quando variantes se parecem. Correção: prefira
#[serde(tag = "type")]para APIs. - Derives grandes em caminhos críticos - derive é bom; evite
serde_json::Valueem todo lugar. Correção: structs tipadas nos limites. - Ignorar
deny_unknown_fieldsem APIs públicas - clientes enviam erros de digitação silenciosamente. Correção: habilite em tipos de requisição. - Crate
chronovstime- escolha um ecossistema. Correção: padronize noCargo.tomldo workspace.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
miniserde | Tamanho mínimo binário | Você precisa da ergonomia completa do derive |
Display manual | Formatos fixos minúsculos | Esquemas em evolução |
protobuf / capnp | gRPC, esquemas estritos | APIs JSON internas rápidas |
FAQs
Preciso de serde_json se eu só usar configuração TOML?
Não. Adicione apenas os crates de formato que você usa. serde sozinho não tem formato.
Posso serializar dados emprestados?
Sim com #[serde(borrow)] e Deserialize<'de> quando os tempos de vida são explícitos. Tipos de propriedade são mais simples para APIs.
Como pular campos None em JSON?
Use #[serde(skip_serializing_if = "Option::is_none")] em campos Option.
Serde é lento?
O código gerado por derive é rápido. Gargalos geralmente são IO e alocação, não o próprio serde.
Relacionados
- fundamentos do serde - seção completa
- JSON com serde_json - cargas úteis de API
- anyhow & thiserror - tipos de erro que serializam de forma limpa
- Melhores Práticas de Crates Essenciais - higiene de dependências
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.