use celers_protocol::{
builder::MessageBuilder,
security::{ContentTypeWhitelist, SecurityPolicy},
};
use serde_json::json;
fn main() {
println!("=== Message Validation Example ===\n");
println!("1. Basic message validation:");
let msg = MessageBuilder::new("tasks.validate")
.args(vec![json!("data")])
.build()
.unwrap();
match msg.validate() {
Ok(_) => println!("✓ Message is valid\n"),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("2. Invalid message (empty task name):");
let mut invalid_msg = MessageBuilder::new("tasks.test").build().unwrap();
invalid_msg.headers.task = "".to_string();
match invalid_msg.validate() {
Ok(_) => println!("✓ Message is valid\n"),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("3. Invalid priority:");
let mut priority_msg = MessageBuilder::new("tasks.test").build().unwrap();
priority_msg.properties.priority = Some(15);
match priority_msg.validate() {
Ok(_) => println!("✓ Message is valid\n"),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("4. Content-type whitelist (safe mode):");
let whitelist = ContentTypeWhitelist::safe();
let json_valid = whitelist.is_allowed("application/json");
let pickle_valid = whitelist.is_allowed("application/x-python-serialize");
println!(" JSON allowed: {}", json_valid);
println!(" Pickle allowed: {} (security risk!)\n", pickle_valid);
println!("5. Strict whitelist (JSON only):");
let strict = ContentTypeWhitelist::strict();
println!(" JSON allowed: {}", strict.is_allowed("application/json"));
println!(
" MessagePack allowed: {}\n",
strict.is_allowed("application/x-msgpack")
);
println!("6. Security policy validation:");
let policy = SecurityPolicy::standard();
let msg = MessageBuilder::new("tasks.secure")
.args(vec![json!("data")])
.build()
.unwrap();
match policy.validate_message(&msg.content_type, msg.body.len(), &msg.headers.task) {
Ok(_) => println!("✓ Message passed security policy\n"),
Err(e) => println!("✗ Security error: {}\n", e),
}
println!("7. Message size limit:");
let large_data = "x".repeat(1_000_000); let large_msg = MessageBuilder::new("tasks.large")
.args(vec![json!(large_data)])
.build()
.unwrap();
match large_msg.validate() {
Ok(_) => println!(
"✓ Large message is valid (size: {} bytes)\n",
large_msg.body.len()
),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("8. Custom size limit (1KB max):");
let msg = MessageBuilder::new("tasks.test")
.args(vec![json!("x".repeat(5000))])
.build()
.unwrap();
match msg.validate_with_limit(1024) {
Ok(_) => println!("✓ Message within limit\n"),
Err(e) => println!("✗ Size error: {}\n", e),
}
println!("9. ETA/Expiration validation:");
use chrono::{Duration, Utc};
let valid_msg = MessageBuilder::new("tasks.scheduled")
.eta(Utc::now() + Duration::hours(1))
.expires_in(Duration::hours(2))
.build()
.unwrap();
match valid_msg.validate() {
Ok(_) => println!("✓ ETA before expiration\n"),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("10. Invalid ETA/Expiration (ETA after expiration):");
let mut invalid_eta = MessageBuilder::new("tasks.invalid").build().unwrap();
invalid_eta.headers.eta = Some(Utc::now() + Duration::hours(2));
invalid_eta.headers.expires = Some(Utc::now() + Duration::hours(1));
match invalid_eta.validate() {
Ok(_) => println!("✓ Valid\n"),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("11. Retry limit validation:");
let mut high_retries = MessageBuilder::new("tasks.retry").build().unwrap();
high_retries.headers.retries = Some(1001);
match high_retries.validate() {
Ok(_) => println!("✓ Valid\n"),
Err(e) => println!("✗ Validation error: {}\n", e),
}
println!("=== Validation Complete ===");
println!("\nBest practices:");
println!("- Always validate messages before sending");
println!("- Use content-type whitelists to block unsafe formats (pickle)");
println!("- Enforce size limits to prevent memory issues");
println!("- Use security policies for additional checks");
}