Introduction : pourquoi JSON est important en Rust
\n\nJSON (JavaScript Object Notation) est un format léger d'échange de données qui est devenu le standard de facto pour les API web, les fichiers de configuration et les interactions entre services. En Rust, un langage de programmation système axé sur la sécurité et les performances, le travail avec JSON est réalisé via un puissant écosystème de crates (bibliothèques).
\n\nBien que Rust ne dispose pas de support intégré pour JSON (contrairement à JavaScript ou Python), son système de types et son approche de la gestion de la mémoire rendent le traitement de JSON non seulement sûr, mais aussi incroyablement rapide. Dans cet article, nous allons voir comment analyser JSON en structures Rust, comment sérialiser les données en JSON et comment éviter les erreurs typiques des débutants.
\n\nL'outil principal pour travailler avec JSON en Rust est la crate serde (framework de sérialisation/désérialisation) associée à serde_json. Ces bibliothèques offrent des abstractions à coût nul (zero-cost abstractions) et prennent en charge des structures de données imbriquées complexes.
Installation et configuration des dépendances
\n\nAvant de commencer, créez un nouveau projet Rust et ajoutez les dépendances nécessaires dans le fichier Cargo.toml :
[dependencies]\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\n\nLe flag features = ["derive"] pour la crate serde permet d'utiliser les macros #[derive(Serialize, Deserialize)], qui génèrent automatiquement le code pour convertir vos structures en JSON et vice versa. C'est une caractéristique clé de Rust : vous écrivez un minimum de code standard, et le compilateur prend en charge le travail de routine.
Après avoir ajouté les dépendances, exécutez cargo build pour télécharger et compiler les bibliothèques.
Analyse JSON en structures Rust (désérialisation)
\n\nCréation du modèle de données
\n\nLa première chose à faire est de définir les structures Rust qui correspondent à vos données JSON. Supposons que nous ayons un JSON représentant les informations d'un utilisateur :
\n\n{\n "name": "Alexeï",\n "age": 30,\n "email": "alexey@example.com",\n "is_active": true\n}\n\nCréons la structure correspondante et ajoutons les attributs de sérialisation :
\n\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\nstruct User {\n name: String,\n age: u32,\n email: String,\n is_active: bool,\n}\n\nLa macro #[derive(Debug)] permet d'afficher la structure dans la console pour le débogage. Sans elle, vous ne pourrez pas utiliser println!("{:?}", user).
Analyse d'une chaîne JSON
\n\nÉcrivons maintenant une fonction qui prend une chaîne JSON et retourne une structure User :
fn parse_user(json_str: &str) -> Result<User, serde_json::Error> {\n let user: User = serde_json::from_str(json_str)?;\n Ok(user)\n}\n\nfn main() {\n let data = r#"\n {\n "name": "Alexeï",\n "age": 30,\n "email": "alexey@example.com",\n "is_active": true\n }\n "#;\n\n match parse_user(data) {\n Ok(user) => println!("Utilisateur : {:?}", user),\n Err(e) => eprintln!("Erreur d'analyse : {}", e),\n }\n}\n\nPoint clé : serde_json::from_str fait automatiquement correspondre les champs JSON avec les champs de la structure. Si les noms des champs dans JSON diffèrent de ceux en Rust (par exemple, JSON utilise snake_case et Rust camelCase), vous pouvez utiliser l'attribut #[serde(rename = "nom_du_champ")].
Traitement des structures imbriquées
\n\nJSON contient souvent des objets imbriqués. Prenons l'exemple d'une adresse utilisateur :
\n\n{\n "name": "Alexeï",\n "address": {\n "city": "Moscou",\n "street": "Tverskaïa",\n "zip": "101000"\n }\n}\n\nCréons les structures imbriquées :
\n\n#[derive(Debug, Serialize, Deserialize