use elicitation::contracts::{And, Established, Prop, both};
struct EmailValidated;
struct PasswordStrong;
struct ConsentObtained;
impl Prop for EmailValidated {}
impl Prop for PasswordStrong {}
impl Prop for ConsentObtained {}
fn validate_email(email: &str) -> Option<Established<EmailValidated>> {
if email.contains('@') && email.contains('.') {
println!("✓ Email validated: {}", email);
Some(Established::assert())
} else {
println!("✗ Invalid email format");
None
}
}
fn validate_password(password: &str) -> Option<Established<PasswordStrong>> {
if password.len() >= 8 {
println!("✓ Password is strong enough");
Some(Established::assert())
} else {
println!("✗ Password too weak");
None
}
}
fn get_consent() -> Established<ConsentObtained> {
println!("✓ Consent obtained");
Established::assert()
}
fn register_user(
email: String,
password: String,
_proof: Established<And<And<EmailValidated, PasswordStrong>, ConsentObtained>>,
) {
println!("\n🎉 User registered successfully!");
println!(" Email: {}", email);
println!(" Password: {} chars", password.len());
}
fn main() {
println!("=== Basic Proof-Carrying Code Example ===\n");
let email = "user@example.com";
let password = "secure123";
println!("Step 1: Validate email");
let email_proof = match validate_email(email) {
Some(proof) => proof,
None => {
println!("\nRegistration failed: invalid email");
return;
}
};
println!("\nStep 2: Validate password");
let password_proof = match validate_password(password) {
Some(proof) => proof,
None => {
println!("\nRegistration failed: weak password");
return;
}
};
println!("\nStep 3: Get consent");
let consent_proof = get_consent();
println!("\nStep 4: Combine proofs");
let email_and_password = both(email_proof, password_proof);
println!("✓ Email and password proofs combined");
let all_proofs = both(email_and_password, consent_proof);
println!("✓ All proofs combined");
println!("\nStep 5: Register user");
register_user(email.to_string(), password.to_string(), all_proofs);
println!("\n=== Key Takeaway ===");
println!("The type system prevents calling register_user() without");
println!("establishing all required preconditions. No runtime checks needed!");
}