Сериализация объектов в Rust: Serde и другие инструменты

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

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

Начать курс

Сериализация объектов в Rust: обзор библиотек и инструментов

Сериализация — один из фундаментальных процессов в разработке программного обеспечения. Она позволяет преобразовывать сложные структуры данных (объекты, структуры, перечисления) в последовательный формат, удобный для хранения на диске или передачи по сети. Обратный процесс — десериализация — восстанавливает исходные объекты из этого формата. В языке Rust эту задачу решает экосистема, центральное место в которой занимает библиотека Serde (Serialization/Deserialization).

В этой статье мы подробно разберём, как работает сериализация в Rust, какие библиотеки для неё существуют, и как использовать их на практике.

Почему Serde?

Serde — это не просто библиотека, а фреймворк для сериализации и десериализации. Его главная особенность — разделение на две части:

  • Serde Data Model — ядро, которое определяет, как типы данных Rust преобразуются в промежуточное представление.
  • Адаптеры форматов — отдельные крейты, которые работают с конкретными форматами (JSON, YAML, TOML, Bincode, MessagePack и другие).

Такой подход позволяет использовать один и тот же код для работы с разными форматами, меняя только одну строку в Cargo.toml.

Подключение и базовая настройка

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

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

Ключевая особенность — использование атрибута #[derive(Serialize, Deserialize)]. Он автоматически генерирует код для преобразования ваших структур:

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct User {
    id: u64,
    name: String,
    email: String,
    is_active: bool,
}

fn main() {
    let user = User {
        id: 42,
        name: "Алексей".to_string(),
        email: "alex@example.com".to_string(),
        is_active: true,
    };

    // Сериализация в JSON
    let json = serde_json::to_string_pretty(&user).unwrap();
    println!("JSON:\n{}", json);

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

Работа с разными форматами

Serde поддерживает десятки форматов. Рассмотрим наиболее популярные:

JSON (serde_json)

Самый распространённый формат для веб-API. Человекочитаемый, но занимает много места.

// Сериализация в строку
let json_str = serde_json::to_string(&data)?;

// Сериализация в поток (файл)
let file = std::fs::File::create("data.json")?;
let writer = std::io::BufWriter::new(file);
serde_json::to_writer(writer, &data)?;

// Чтение из файла
let file = std::fs::File::open("data.json")?;
let reader = std::io::BufReader::new(file);
let data: MyStruct = serde_json::from_reader(reader)?;

Bincode (bincode)

Бинарный формат — компактный и быстрый. Идеален для внутреннего хранения или передачи между сервисами на Rust.

// Cargo.toml: bincode = "1.3"

let encoded: Vec<u8> = bincode::serialize(&data)?;
let decoded: MyStruct = bincode::deserialize(&encoded)?;

YAML и TOML (serde_yaml, toml)

Используются для конфигурационных файлов. Человекочитаемые, поддерживают комментарии (YAML).

// YAML
let yaml = serde_yaml::to_string(&data)?;
let data: MyStruct = serde_yaml::from_str(&yaml)?;

// TOML (популярен в экосистеме Rust)
let toml = toml::to_string(&data)?;
let data: MyStruct = toml::from_str(&toml)?;

Продвинутые возможности: атрибуты Serde

Serde предоставляет мощные атрибуты для тонкой настройки сериализации:

#[derive(Serialize, Deserialize)]
struct Config {
    #[serde(rename = "server_host")]
    host: String,

    #[serde(default = "default_port")]
    port: u16,

    #[serde(skip_serializing_if = "Option::is_none")]
    optional_field: Option<String>,

    #[serde(flatten)]
    extra: std::collections::HashMap<String, String>,
}

fn default_port() -> u16 { 8080 }

Ключевые атрибуты:

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