Валидация данных в 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 Также в библиотеке
Работа с YAML в TypeScript: полное руководство по парсингу и сериализации
ORM для Swift (iOS/macOS): сравнение и примеры использования
Работа с изображениями на Swift: resize и crop для iOS/macOS
Ardalis.SmartEnum для C# (.NET): полное руководство с примерами