JSON обработка в Rust: библиотека serde_json для образовательного сайта

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

JSON обработка в Rust: полное руководство с serde_json

JSON (JavaScript Object Notation) — один из самых популярных форматов обмена данными в веб-разработке. В Rust обработка JSON выполняется с помощью мощной библиотеки serde_json, которая является частью экосистемы Serde — фреймворка для сериализации и десериализации структур данных. В этой статье мы подробно разберём, как работать с JSON в Rust: от установки до сложных примеров с вложенными структурами.

Установка и настройка

Для начала работы добавьте зависимости в файл Cargo.toml:

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

Библиотека serde предоставляет макросы #[derive(Serialize, Deserialize)], а serde_json отвечает за преобразование данных в JSON и обратно.

Базовая сериализация и десериализация

Рассмотрим простой пример: создадим структуру User и научимся преобразовывать её в JSON и обратно.

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

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

fn main() {
    // Создаём экземпляр структуры
    let user = User {
        name: "Алексей".to_string(),
        age: 30,
        email: "alex@example.com".to_string(),
    };

    // Сериализация в строку JSON
    let json_string = serde_json::to_string(&user).unwrap();
    println!("JSON: {}", json_string);

    // Десериализация из JSON обратно в структуру
    let deserialized_user: User = serde_json::from_str(&json_string).unwrap();
    println!("Десериализовано: {:?}", deserialized_user);
}

Результат выполнения:

JSON: {"name":"Алексей","age":30,"email":"alex@example.com"}
Десериализовано: User { name: "Алексей", age: 30, email: "alex@example.com" }

Работа с вложенными структурами

JSON часто содержит вложенные объекты и массивы. Rust позволяет легко моделировать такие структуры:

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

#[derive(Debug, Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    address: Address,
    hobbies: Vec<String>,
}

fn main() {
    let person = Person {
        name: "Мария".to_string(),
        age: 25,
        address: Address {
            city: "Москва".to_string(),
            street: "Тверская".to_string(),
            house: 10,
        },
        hobbies: vec!["чтение".to_string(), "спорт".to_string()],
    };

    // Красивый вывод JSON с отступами
    let pretty_json = serde_json::to_string_pretty(&person).unwrap();
    println!("{}", pretty_json);
}

Вывод:

{
  "name": "Мария",
  "age": 25,
  "address": {
    "city": "Москва",
    "street": "Тверская",
    "house": 10
  },
  "hobbies": [
    "чтение",
    "спорт"
  ]
}

Обработка ошибок и необязательных полей

В реальных проектах данные могут быть неполными. Rust предлагает элегантные способы обработки таких ситуаций:

  • Option<T> — для необязательных полей
  • Result<T, E> — для обработки ошибок парсинга
  • Атрибуты Serde — для настройки поведения сериализации
use serde::{Serialize, Deserialize};
use serde_json::Result;

#[derive(Debug, Serialize, Deserialize)]
struct Product {
    name: String,
    price: f64,
    #[serde(default)] // Значение по умолчанию, если поле отсутствует
    description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")] // Пропустить, если None
    discount: Option<f64>,
}

fn parse_product(json_str: &str) -> Result<Product> {
    let product: Product = serde_json::from_str(json_str)?;
    Ok(product)
}

fn main() {
    // JSON без необязательных полей
    let json1 = r#"{"name": "Ноутбук", "price": 79999.99}"#;
    let product1 = parse_product(json1).unwrap();
    println!("{:?}", product1);

    // JSON с полным набором полей
    let json2 = r#"{"name": "Мышь", "price": 2499.50, "description": "Беспроводная", "discount": 10                    

Рекомендаций