100 % local — seus dados nunca saem do seu navegador

JSON para Rust — structs serde prontas a derivar

Transforme uma amostra JSON em structs Rust com derives do serde. Os nomes viram snake_case sem perder a chave: o from_str funciona de primeira.

Instantâneo Privado Zero cookies

Entrada JSON

Saída Rust

O que esta ferramenta faz

Uma amostra JSON vira structs Rust com derivações serde.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Root {
    pub id: i64,
    #[serde(rename = "firstName")]
    pub first_name: String,
    pub address: Address,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Address {
    pub city: String,
}

Os nomes de campo do Rust vão em snake_case: firstName vira first_name — e #[serde(rename)] guarda a chave, porque um struct que não lê mais o seu próprio JSON seria pior que um nome pouco idiomático. O rename só aparece onde os dois divergem.

Se você apenas lê a carga, a opção que tira Serialize te dá #[derive(Debug, Deserialize)] e um trait a menos para satisfazer.

As palavras-chave, cruas ou com sufixo

{ "type": "user", "self": "/users/1" }
    pub r#type: String,
    #[serde(rename = "self")]
    pub self_: String,

r#type é um identificador cru: o serde já o serializa como type, nenhum atributo é preciso. self é uma das poucas palavras que o Rust não aceita nem como identificador cru — self, Self, crate, super — então recebe um sublinhado e um rename.

O que vem do serde_json

null, os valores desconhecidos, os arrays vazios e os mistos acabam todos em serde_json::Value:

    pub nickname: Option<serde_json::Value>,
    pub tags: Vec<serde_json::Value>,

então o serde_json tem lugar no seu Cargo.toml, ao lado do serde com o recurso derive. O caminho é escrito inteiro em vez de importado, o que mantém a saída válida seja qual for a organização dos seus módulos.

O que uma amostra não consegue dizer

Só null produz um Option. Todo o resto é obrigatório, porque o documento trazia um valor — e «às vezes ausente» não é algo que um documento possa mostrar. Envolver um campo em Option<T> é um retoque; #[serde(default)] é outro, quando a ausência deve valer o padrão em vez de um erro.

Duas chaves que dão o mesmo snake_case — fooBar e foo_bar — levam sufixo em vez de se fundirem, e cada uma guarda o seu rename.

Privado por padrão

Tudo é executado localmente no seu navegador com JavaScript. Os seus dados nunca são enviados para um servidor, o que torna a ferramenta segura para conteúdo sensível e funciona offline.

Perguntas frequentes

O que preciso no Cargo.toml?
`serde` com o recurso `derive`, e `serde_json` assim que um campo carregar um valor desconhecido: `Option<serde_json::Value>` e `Vec<serde_json::Value>` vêm desse crate. A saída usa o caminho completo em vez de importá-lo, então nada quebra se você o apelidar de outro jeito.
Como é tratada uma chave chamada `type` ou `self`?
`type` vira o identificador cru `r#type`, que o serde serializa como `type` — sem atributo nenhum. `self` não pode ser identificador cru de jeito algum, então vira `self_` com `#[serde(rename = "self")]` para guardar a chave. Os dois casos saem escritos como o compilador aceita.
Por que meu identificador de vinte dígitos é um `i64`?
Porque é o inteiro natural do Rust para JSON, e vai até cerca de 9,2 × 10¹⁸. Um mais longo não cabe: o serde_json relata um erro na desserialização em vez de truncar. Se o campo for um identificador floco de neve, `u64` ganha um bit e `String` é o que a maioria das APIs espera de fato.

Conversores relacionados