100 % local — vos données ne quittent jamais votre navigateur

JSON en Rust — des structs serde prêtes à dériver

Transformez un échantillon JSON en structs Rust avec dérives serde. Les noms passent en snake_case sans perdre la clé : from_str marche du premier coup.

Instantané Privé Zéro cookie

Entrée JSON

Sortie Rust

Ce que fait cet outil

Un échantillon JSON devient des structs Rust avec les dérivations 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,
}

Les noms de champs Rust sont en snake_case : firstName devient first_name — et #[serde(rename)] garde la clé, parce qu’une struct qui ne relit plus son propre JSON serait pire qu’un nom peu idiomatique. Le rename n’apparaît que là où les deux diffèrent.

Si vous ne faites que lire la charge, l’option qui retire Serialize vous donne #[derive(Debug, Deserialize)] et un trait de moins à satisfaire.

Les mots-clés, bruts ou suffixés

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

r#type est un identifiant brut : serde le sérialise déjà en type, aucun attribut n’est nécessaire. self fait partie des rares mots que Rust n’accepte même pas en identifiant brut — self, Self, crate, super — il reçoit donc un tiret bas et un rename.

Ce qui vient de serde_json

null, les valeurs inconnues, les tableaux vides et les tableaux mêlés finissent tous en serde_json::Value :

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

serde_json a donc sa place dans votre Cargo.toml, à côté de serde et de sa fonctionnalité derive. Le chemin est écrit en entier plutôt qu’importé, ce qui garde la sortie valide quelle que soit l’organisation de vos modules.

Ce qu’un échantillon ne peut pas dire

Seul null produit une Option. Tout le reste est obligatoire, parce que le document avait une valeur — et « parfois absent » n’est pas quelque chose qu’un document puisse montrer. Envelopper un champ dans Option<T> est une retouche ; #[serde(default)] en est une autre, quand l’absence doit valoir la valeur par défaut plutôt qu’une erreur.

Deux clés qui donnent le même snake_case — fooBar et foo_bar — sont suffixées plutôt que fondues, et chacune garde son rename.

Confidentiel par conception

Tout s’exécute localement dans votre navigateur en JavaScript. Vos données ne sont jamais envoyées sur un serveur, ce qui rend l’outil sûr pour des contenus sensibles, et il fonctionne hors ligne.

Questions fréquentes

Que faut-il dans Cargo.toml ?
`serde` avec la fonctionnalité `derive`, et `serde_json` dès qu’un champ porte une valeur inconnue : `Option<serde_json::Value>` et `Vec<serde_json::Value>` viennent de cette caisse. La sortie emploie le chemin complet plutôt que de l’importer, si bien que rien ne casse si vous l’aliasez autrement.
Comment est traitée une clé nommée `type` ou `self` ?
`type` devient l’identifiant brut `r#type`, que serde sérialise en `type` — aucun attribut nécessaire. `self` ne peut pas être un identifiant brut du tout : il devient `self_` avec `#[serde(rename = "self")]` pour garder la clé. Les deux cas sortent écrits comme le compilateur les accepte.
Pourquoi mon identifiant de vingt chiffres est-il un `i64` ?
Parce que c’est l’entier naturel de Rust pour du JSON, et qu’il va jusqu’à environ 9,2 × 10¹⁸. Un plus long n’y tient pas : serde_json signale une erreur à la désérialisation plutôt que de tronquer. Si le champ est un identifiant flocon, `u64` gagne un bit et `String` est ce qu’attendent la plupart des API.

Convertisseurs associés