Skip to content
jsonforge.app

JSON to Rust

Générez des structs Rust avec derives serde Deserialize depuis un échantillon JSON.

Entrée JSON

Loading editor…

Code généré

Saisissez du JSON à gauche pour générer un type à partir de celui-ci.

Qu'est-ce que JSON to Rust ?

Un convertisseur JSON vers Rust génère les définitions de structs nécessaires pour désérialiser une charge utile JSON avec serde, la crate que pratiquement tout projet Rust utilise pour cela. Rust n'a pas de type objet dynamique de repli, donc consommer une API suppose de déclarer la forme exacte d'avance : un struct par objet, un type concret par champ, et un #[derive(Deserialize)] sur chacun pour que serde génère l'implémentation d'analyse à la compilation. Faire cela à la main pour une réponse profondément imbriquée est lent et répétitif, et le compilateur rejettera l'ensemble pour un seul type incompatible. Ce générateur produit chaque struct dans l'ordre des dépendances avec les attributs de derive déjà attachés, pour que vous puissiez coller le résultat dans un module et que serde_json::from_str fonctionne immédiatement. Les noms de champs sont aussi convertis automatiquement vers le snake_case idiomatique de Rust, et chaque fois que cela diffère de la clé JSON d'origine — ce qui sera le cas pour presque toute charge utile camelCase — un attribut `#[serde(rename = "...")]` est généré sur ce champ précis, pour que vous n'ayez jamais à ajouter d'attributs de renommage à la main.

Comment utiliser JSON to Rust

  1. Collez une réponse JSON représentative dans le panneau de gauche — les champs des structs reflètent exactement les clés présentes dans cet échantillon.
  2. Définissez un nom de struct racine au-dessus de la sortie (par défaut « Root ») ; chaque objet imbriqué devient son propre struct nommé d'après la clé qui le contient.
  3. Ajoutez serde à Cargo.toml avec la feature derive (`serde = { version = "1", features = ["derive"] }`) plus serde_json, puis collez les structs.
  4. Basculez le sélecteur de langue au-dessus de la sortie pour générer la même forme en struct Go ou type TypeScript à la place.

Exemples

Objet plat avec derive Deserialize

Entrée

{"id": 1, "name": "Ada", "active": true}

Sortie

use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct Root { pub id: i64, pub name: String, pub active: bool, }

Un objet imbriqué devient son propre struct

Entrée

{"user": {"id": 1, "name": "Ada", "roles": ["admin"]}}

Sortie

use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct User { pub id: i64, pub name: String, pub roles: Vec<String>, } #[derive(Debug, Deserialize)] pub struct Root { pub user: User, }

Clé camelCase renommée automatiquement en snake_case

Entrée

{"userId": 1, "firstName": "Ada"}

Sortie

use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct Root { #[serde(rename = "userId")] pub user_id: i64, #[serde(rename = "firstName")] pub first_name: String, }

Erreurs courantes

  • Oublier la feature derive sur serde dans Cargo.toml, ce qui produit une erreur de résolution de macro qui ne pointe pas clairement vers le flag de feature manquant.
  • Laisser chaque champ non-Option quand l'API en omet parfois un — serde fait alors échouer toute la désérialisation à l'exécution au lieu de laisser ce seul champ vide.
  • Ajouter votre propre attribut de conteneur #[serde(rename_all = "camelCase")] par-dessus les structs générés — c'est redondant, chaque champ qui en a besoin porte déjà son propre #[serde(rename = "...")].
  • Traiter chaque champ serde_json::Value comme acceptable en l'état — cela compile, mais vous devez quand même matcher dessus à la main pour extraire une valeur exploitable ; c'est le signe que l'échantillon n'a pas fixé le type de ce champ, pas un résultat fini.
  • Marquer un champ Option<T> uniquement parce que JSON autorise techniquement null partout, plutôt que parce que l'échantillon l'a réellement montré manquant ou null — envelopper excessivement chaque champ dans Option<T> rend plus tard une valeur réellement manquante plus difficile à remarquer.

Pourquoi utiliser cet outil

  • Émet les attributs #[derive(Debug, Deserialize)] et l'import serde, pour que la sortie compile telle quelle sans code répétitif à ajouter.
  • Déclare les structs imbriqués dans l'ordre des dépendances, pour que le fichier compile de haut en bas sans réordonnancement manuel.
  • Fonctionne entièrement côté client, donc une réponse utilisée pour générer ces structs ne quitte jamais votre machine avant qu'une seule ligne n'atteigne Cargo.
  • Convertit chaque champ vers le snake_case idiomatique et attache un #[serde(rename = "...")] par champ partout où cela diffère de la clé source, pour qu'une charge utile camelCase compile sans toucher vous-même aux attributs de nommage de serde.
  • Ne retombe sur serde_json::Value que là où un type concret ne peut réellement pas être arrimé — un échantillon uniquement null, ou un tableau mélangeant un entier et un flottant pour la même clé — au lieu de deviner silencieusement le mauvais primitif.

Questions fréquentes