Advanced Validators
This example showcases modern complex constraints (like non_empty, alphanumeric, positive, negative, and non_zero) implemented via tags or dynamic programmatic builders.
Compilable Example
//! Advanced validation rules example showcasing `non_empty`, `alphanumeric`, //! `positive`, `negative`, and `non_zero` validation rules both via declarative //! macros and programmatic builders. use adapters::SchemaValidator; use adapters::prelude::*; use adapters::schema::{FloatSchema, IntegerSchema, ObjectSchema, StringSchema}; /// A financial invoice transaction derived using macro constraints. #[derive(Schema, Debug)] struct TransactionInvoice { /// Reference code must be alphanumeric and non-empty. #[schema(non_empty, alphanumeric)] reference_code: String, /// Number of items must be strictly positive (> 0). #[schema(positive)] quantity: i32, /// Adjustments or discounts must be strictly negative (< 0.0). #[schema(negative)] discount: f32, /// Balance cannot be zero (!= 0). #[schema(non_zero)] balance: i64, } fn main() -> Result<(), Error> { println!("=== 1. Declarative Macro Validation ==="); // Valid Payload let valid_json = r#"{ "reference_code": "INV2026TX", "quantity": 5, "discount": -15.50, "balance": 250 }"#; let invoice = TransactionInvoice::from_json(valid_json)?; println!( "Successfully parsed and validated valid invoice:\n{:#?}\n", invoice ); // Invalid Payload with multiple constraint violations let invalid_json = r#"{ "reference_code": "INV-2026-TX!", "quantity": 0, "discount": 5.50, "balance": 0 }"#; match TransactionInvoice::from_json(invalid_json) { Ok(_) => println!("Error: Expected validation failure but succeeded!"), Err(e) => { println!("Validation failed as expected! Errors:"); println!("{}", e); } } println!("\n=== 2. Programmatic Builder Validation ==="); // Build the identical validation logic programmatically let invoice_schema = ObjectSchema::new() .field( "reference_code", StringSchema::new().required().non_empty().alphanumeric(), ) .field("quantity", IntegerSchema::new().required().positive()) .field("discount", FloatSchema::new().required().negative()) .field("balance", IntegerSchema::new().required().non_zero()); // Validate a dynamic Value payload using our schema let dynamic_invalid_payload = Value::Object( [ ("reference_code".to_string(), Value::String("".to_string())), // Fails non_empty ("quantity".to_string(), Value::Int(-10)), // Fails positive ("discount".to_string(), Value::Float(-5.0)), // Passes negative ("balance".to_string(), Value::Int(0)), // Fails non_zero ] .into_iter() .collect(), ); match invoice_schema.validate(&dynamic_invalid_payload, "invoice") { Ok(_) => println!("Error: Expected programmatic validation failure!"), Err(err) => { println!("Programmatic validation detected constraint violations successfully:"); println!( "Field: {}, Code: {}, Message: {}", err.field, err.code, err.message ); } } Ok(()) }