JSON com serde_json
Analise e emita JSON com structs tipadas, Value dinâmico e streaming para payloads grandes.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
#[derive(Serialize, Deserialize)]
struct Event { kind: String, payload: Value }
let raw = r#"{"kind":"click","payload":{"x":1}}"#;
let ev: Event = serde_json::from_str(raw)?;
let dynamic = json!({ "ok": true, "count": ev.payload["x"] });
let out = serde_json::to_string(&dynamic)?;Quando usar isso: APIs HTTP, arquivos de configuração e logs usam predominantemente JSON em serviços Rust.
Exemplo de Trabalho
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
#[derive(Debug, Serialize, Deserialize)]
struct User {
id: u64,
email: String,
#[serde(default)]
tags: Vec<String>,
}
fn main() -> serde_json::Result<()> {
let u = User { id: 1, email: "a@b.co".into(), tags: vec![] };
let compact = serde_json::to_string(&u)?;
let pretty = serde_json::to_string_pretty(&u)?;
let parsed: User = serde_json::from_str(&compact)?;
assert_eq!(parsed.email, "a@b.co");
let mut v: Value = serde_json::from_str(r#"{"meta":{"version":1}}"#)?;
v["meta"]["source"] = json!("api");
assert_eq!(v["meta"]["version"], 1);
Ok(())
}O que isso demonstra:
to_stringvsto_string_prettypara saída na rede vs depuração.from_strparaUserfortemente tipado.Valuepara JSON parcialmente estruturado ou em evolução.- Macro
json!para construção literal.
Mergulho Profundo
Como Funciona
serde_jsonimplementaSerializereDeserializerdo Serde para JSON.- A desserialização tipada valida a estrutura no momento da análise.
Valueadia a aplicação do esquema até que você indexe os campos.
APIs Comuns
| Função | Uso |
|---|---|
from_str / from_slice | Analisar para T |
to_string / to_vec | Serializar T |
from_value / to_value | Converter Value ↔ T |
json! | Construir literais Value |
Notas Rust
// Acesso a campo falível em Value
let n = v.get("count").and_then(|x| x.as_u64()).unwrap_or(0);Armadilhas
- unwrap na análise - JSON não confiável causa pânico em produção. Correção: Propague
serde_json::Errorou mapeie para 400/422. - f64 para dinheiro - Arredondamento de ponto flutuante em números JSON. Correção: Armazene centavos como inteiros ou use crates decimais.
- Grande DOM em memória -
Valuealoca o documento inteiro. Correção:serde_json::Deserializer::from_readercom tipos de stream. - Perda de UTF-8 - UTF-8 inválido em strings falha na desserialização. Correção: Valide upstream; use bytes apenas quando necessário.
- Chaves duplicadas - A última chave vence em
Value; structs tipadas geram erro em duplicatas por padrão. Correção: Conheça o comportamento do produtor.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
simd-json | Vazão máxima de análise | Builds portáteis sem SIMD |
sonic-rs | JSON de alto desempenho | A maturidade do ecossistema é mais importante |
miniserde | Binário de dependência mínima | Necessidades complexas de derive |
FAQs
Pretty vs compact?
Compacto para a rede; pretty para logs e fixtures apenas.
Analisar sem alocar String?
from_slice em &[u8] ou from_reader em impl Read.
Campos desconhecidos?
#[serde(deny_unknown_fields)] em structs para APIs estritas.
Mesclar objetos JSON?
Manipule Value ou desserialize para HashMap<String, Value>.
JSON Lines?
Leia linha por linha com BufRead::lines e from_str por linha.
Incorporação de JSON bruto?
serde_json::raw::RawValue preserva subárvores como bytes.
Integração com Axum?
O extrator Json<T> usa serde_json internamente.
NaN e Infinito?
Não é JSON padrão; serde_json rejeita floats não finitos por padrão.
Benchmarking?
Use criterion com tamanhos de payload representativos.
Validação de esquema?
Adicione o crate jsonschema após a análise do serde para verificações de contrato.
Relacionado
- Fundamentos do Serde - Fundamentos do Derive
- Personalizando a Serialização - Atributos de campo
- Tratamento de Erros e Validação - Entrada não confiável
- Outros Formatos - TOML, YAML, bincode
- Validação de Requisição - Limite da Web
Versões da Stack: 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+.