fn main() -> hexser::HexResult<()> {
println!("=== Tutorial 02: Repository Port ===\n");
#[derive(Clone, Debug)]
struct User {
id: String,
email: String,
name: String,
}
impl hexser::domain::HexEntity for User {
type Id = String;
}
trait UserRepository: hexser::ports::Repository<User> {
fn find_by_email(&self, email: &str) -> hexser::HexResult<Option<User>>;
fn count(&self) -> hexser::HexResult<usize>;
}
println!("✅ Defined UserRepository port");
println!(" - Extends base Repository<User> trait");
println!(" - Adds custom queries: find_by_email, count");
println!(" - Lives in the Port layer (interfaces only!)");
println!("\n🎯 Architecture so far:");
println!(" ┌─────────────────┐");
println!(" │ Domain │ ← User entity");
println!(" │ [User] │");
println!(" └────────┬────────┘");
println!(" │ depends on");
println!(" ↓");
println!(" ┌─────────────────┐");
println!(" │ Port │ ← UserRepository interface");
println!(" │ [UserRepository]│");
println!(" └─────────────────┘");
println!("\n📚 What you learned:");
println!(" - Ports define interfaces (the WHAT)");
println!(" - Domain depends on ports, not implementations");
println!(" - Custom methods extend base functionality");
println!("\n💡 Why this matters:");
println!(" - You can now implement this with ANY database");
println!(" - Domain code never changes when switching databases");
println!(" - Easy to mock for testing");
println!("\n✅ Tutorial 02 Complete!");
println!("Next: `cargo run --example tutorial_03_adapter`");
Ok(())
}