anycms-core 0.5.4

A unified API response library supporting multiple Rust web frameworks
Documentation
//! validator crate 集成示例
//!
//! 演示如何将 `validator::ValidationErrors` 自动转换为 `ApiResult` 响应
//!
//! 运行方式:
//!   cargo run --example validator_demo --features validator

#![cfg(feature = "validator")]

use anycms_core::{ApiResult, FieldError, validation_errors_to_field_errors};
use serde::Serialize;
use validator::Validate;

// ============================================================
// 示例数据模型
// ============================================================

#[derive(Debug, Serialize, Validate)]
struct SignupData {
    #[validate(email(message = "邮箱格式不正确"))]
    email: String,
    #[validate(length(min = 1, message = "用户名不能为空"))]
    name: String,
    #[validate(range(min = 18, max = 120, message = "年龄必须在 18 到 120 之间"))]
    age: u8,
}

#[derive(Debug, Validate)]
struct Address {
    #[validate(length(min = 1, message = "街道不能为空"))]
    street: String,
    #[validate(length(min = 1, message = "城市不能为空"))]
    city: String,
}

#[derive(Debug, Validate)]
struct Order {
    #[validate(length(min = 1))]
    id: String,
    #[validate(nested)]
    shipping_address: Address,
}

fn main() {
    println!("=== validator crate 集成示例 ===\n");

    // ----------------------------------------------------------
    // 1. 验证通过 — 返回成功响应
    // ----------------------------------------------------------
    println!("1. 验证通过:");
    println!("   输入: email=test@example.com, name=Alice, age=25\n");

    let data = SignupData {
        email: "test@example.com".into(),
        name: "Alice".into(),
        age: 25,
    };

    let result: ApiResult<String> = match data.validate() {
        Ok(_) => ApiResult::value("注册成功".into()),
        Err(e) => e.into(),
    };

    println!("   {}", serde_json::to_string_pretty(&result).unwrap());
    println!();

    // ----------------------------------------------------------
    // 2. 验证失败 — 多字段错误自动转换为 422 响应
    // ----------------------------------------------------------
    println!("2. 验证失败(多字段错误):");
    println!("   输入: email=not-an-email, name=(空), age=5\n");

    let bad = SignupData {
        email: "not-an-email".into(),
        name: "".into(),
        age: 5,
    };

    let result: ApiResult<String> = match bad.validate() {
        Ok(_) => ApiResult::value("ok".into()),
        Err(e) => e.into(),
    };

    println!("   {}", serde_json::to_string_pretty(&result).unwrap());
    println!();

    // ----------------------------------------------------------
    // 3. 使用 validation_errors_to_field_errors 手动检查错误
    // ----------------------------------------------------------
    println!("3. 手动提取字段错误:");

    let bad2 = SignupData {
        email: "bad".into(),
        name: "".into(),
        age: 200,
    };

    if let Err(errors) = bad2.validate() {
        let field_errors = validation_errors_to_field_errors(&errors);
        println!("   字段错误列表:");
        for fe in &field_errors {
            println!("     - {}: {}", fe.field, fe.message);
        }
    }
    println!();

    // ----------------------------------------------------------
    // 4. 嵌套结构体验证 — 字段名自动前缀
    // ----------------------------------------------------------
    println!("4. 嵌套结构体验证:");

    let order = Order {
        id: "ORD-001".into(),
        shipping_address: Address {
            street: "".into(),
            city: "".into(),
        },
    };

    let result: ApiResult<String> = match order.validate() {
        Ok(_) => ApiResult::value("ok".into()),
        Err(e) => {
            let field_errors = validation_errors_to_field_errors(&e);
            for fe in &field_errors {
                println!("     - {}: {}", fe.field, fe.message);
            }
            ApiResult::validation_errors(field_errors)
        }
    };

    println!();
    println!("   响应 JSON:");
    println!("   {}", serde_json::to_string_pretty(&result).unwrap());
    println!();

    // ----------------------------------------------------------
    // 5. 手动合并 validator 错误与自定义错误
    // ----------------------------------------------------------
    println!("5. 合并 validator 错误与自定义错误:");

    let bad3 = SignupData {
        email: "test@example.com".into(),
        name: "admin".into(),
        age: 25,
    };

    let mut errors: Vec<FieldError> = Vec::new();

    // 先收集 validator 的错误
    if let Err(ve) = bad3.validate() {
        errors.extend(validation_errors_to_field_errors(&ve));
    }

    // 再添加自定义业务校验错误
    if bad3.name == "admin" {
        errors.push(FieldError::new("name", "用户名 'admin' 已被保留"));
    }

    if !errors.is_empty() {
        let result = ApiResult::<String>::validation_errors(errors);
        println!("   {}", serde_json::to_string_pretty(&result).unwrap());
    }

    println!();
    println!("=== 示例结束 ===");
}