Валидация данных в Rust: обзор библиотек и фреймворков

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

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

Начать курс

Валидация данных в Rust: обзор библиотек и фреймворков

Валидация данных — критически важный этап разработки любого приложения на Rust. От корректности проверки входных данных зависит безопасность, стабильность и предсказуемость работы программы. В экосистеме Rust существует несколько зрелых решений для валидации, каждое из которых имеет свои особенности. В этой статье мы подробно рассмотрим три основные библиотеки: validator, garde и validify, а также коснёмся встроенных возможностей serde.

1. Библиотека validator

validator — наиболее популярная библиотека для валидации структур данных. Она предоставляет атрибуты для аннотирования полей структур и автоматической генерации кода проверки через derive-макросы.

Установка

[dependencies]
validator = { version = "0.18", features = ["derive"] }

Пример использования

use validator::Validate;

#[derive(Debug, Validate)]
struct User {
    #[validate(length(min = 3, max = 50))]
    username: String,

    #[validate(email)]
    email: String,

    #[validate(range(min = 18, max = 120))]
    age: u8,

    #[validate(required)]
    phone: Option<String>,
}

fn main() {
    let user = User {
        username: "Jo".to_string(),
        email: "invalid-email".to_string(),
        age: 15,
        phone: None,
    };

    match user.validate() {
        Ok(_) => println!("Данные корректны"),
        Err(errors) => {
            for (field, err) in &errors {
                println!("Ошибка в поле '{}': {:?}", field, err);
            }
        }
    }
}

Основные возможности validator

  • Встроенные валидаторы: email, url, phone, credit_card, ip, must_match и другие.
  • Проверка длин строк, числовых диапазонов, регулярных выражений.
  • Валидация вложенных структур через #[validate(nested)].
  • Поддержка пользовательских валидаторов через custom.

2. Библиотека garde

garde — современный и производительный фреймворк валидации, который позиционируется как альтернатива validator с улучшенной производительностью и более гибкой системой правил.

Установка

[dependencies]
garde = "0.21"

Пример использования

use garde::Validate;

#[derive(Debug, Validate)]
struct RegisterForm {
    #[garde(length(min = 3, max = 50))]
    username: String,

    #[garde(email)]
    email: String,

    #[garde(range(min = 18))]
    age: u32,

    #[garde(ascii)]
    password: String,
}

fn main() {
    let form = RegisterForm {
        username: "a".to_string(),
        email: "test".to_string(),
        age: 15,
        password: "пароль".to_string(),
    };

    if let Err(errors) = form.validate() {
        for error in errors {
            println!("Ошибка: {}", error.message);
        }
    } else {
        println!("Форма валидна");
    }
}

Преимущества garde

  • Высокая производительность за счёт минимизации аллокаций.
  • Поддержка асинхронных валидаторов.
  • Богатый набор встроенных правил: email, url, ip, phone, credit_card, pattern и другие.
  • Группировка правил и контекстная валидация.
  • Возможность создания кастомных валидаторов с произвольной логикой.

3. Библиотека validify

validify — фреймворк, который интегрируется с serde и предоставляет удобный способ валидации данных сразу после десериализации. Это особенно полезно при работе с веб-фреймворками (actix-web, axum).

Установка

[dependencies]
validify = "3.0"

Пример использования

use validify::Validify;

#[derive(Debug, Validify)]
struct CreateUser {
    #[validate(length(min = 3, max = 50))]
    username: String,

    #[validate(email)]
    email: String,

    #[validate(range(min = 18))]
    age: u32,

    #[modify(trim, lowercase)]
    #[validate(length(min = 6))]
    password: String,
}

fn main() {
    let mut user = CreateUser {
        username: "Al".to_string(),
        email: "invalid".to_string(),
        age: 17,
        password: " Pass ".to_string                    

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