JSON Processing in Rust: serde_json and json Libraries

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

JSON Processing in Rust: serde_json and Working with Data



JSON (JavaScript Object Notation) remains one of the most popular data exchange formats in web development, APIs, and configuration files. In the Rust language, known for its performance and safety, working with JSON is implemented through a powerful ecosystem of crates. The main tool is the serde_json library, built on the serde serialization framework. In this article, we will thoroughly examine how to parse, create, and transform JSON in Rust, as well as consider alternative approaches.



1. Installing and Importing serde_json



To get started, add dependencies to the Cargo.toml file:



[dependencies]serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"


serde provides the Serialize and Deserialize traits, while serde_json provides the specific implementation for JSON. After adding the crates, you can import them into your code:



use serde::{Deserialize, Serialize};use serde_json::Result;


2. Serializing Structs to JSON



To convert a Rust struct to JSON, you need to annotate it with the #[derive(Serialize)] attribute. Consider an example with user data:



#[derive(Serialize)]struct User {    name: String,    age: u8,    email: String,    active: bool,}

fn main() -> Result<()> { let user = User { name: "Alexey".to_string(), age: 30, email: "alex@example.com".to_string(), active: true, };

let json = serde_json::to_string(&user)?; println!("{}", json); // Output: {"name":"Alexey","age":30,"email":"alex@example.com","active":true} Ok(())}


The serde_json::to_string method returns Result<String>. For formatted output, use serde_json::to_string_pretty.



3. Deserializing JSON into Structs



The reverse process — converting a JSON string into a Rust struct. For this, the struct must implement Deserialize:



#[derive(Deserialize, Debug)]struct User {    name: String,    age: u8,    email: String,    active: bool,}

fn main() -> Result<()> { let data = r#" { "name": "Maria", "age": 25, "email": "maria@example.com", "active": false }"#;

let user: User = serde_json::from_str(data)?; println!("{:?}", user); // Output: User { name: "Maria", age: 25, email: "maria@example.com", active: false } Ok(())}


If the JSON contains fields missing from the struct, or vice versa, use the #[serde(default)] or #[serde(skip_serializing_if = "Option::is_none")] attributes.



4. Working with Arbitrary JSON (Value)



Sometimes the data structure is not known in advance. In such cases, the serde_json::Value enum is used, which can represent any JSON type:



use serde_json::Value;

fn main() -> Result<()> { let data = r#" { "name": "Ivan", "age": 35, "hobbies": ["reading", "programming"], "address": null }"#;

let v: Value = serde_json::from_str(data)?;

// Accessing fields if let Some(name) = v.get("name") { println!("Name: {}", name); }

// Extracting an array if let Some(hobbies) = v.get("hobbies").and_then(|h| h.as_array()) { for hobby in hobbies { println!("Hobby: {}", hobby); } }

Ok(())}


Value supports methods like as_str(), as_u64(), as_array(), and others for safe data extraction.

Recommendations