use adapters::SchemaValidator;
use adapters::prelude::*;
use adapters::schema::{FloatSchema, IntegerSchema, ObjectSchema, StringSchema};
#[derive(Schema, Debug)]
struct TransactionInvoice {
#[schema(non_empty, alphanumeric)]
reference_code: String,
#[schema(positive)]
quantity: i32,
#[schema(negative)]
discount: f32,
#[schema(non_zero)]
balance: i64,
}
fn main() -> Result<(), Error> {
println!("=== 1. Declarative Macro Validation ===");
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
);
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 ===");
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());
let dynamic_invalid_payload = Value::Object(
[
("reference_code".to_string(), Value::String("".to_string())), ("quantity".to_string(), Value::Int(-10)), ("discount".to_string(), Value::Float(-5.0)), ("balance".to_string(), Value::Int(0)), ]
.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(())
}