//! FAPP Service Demo //! //! Demonstrates therapist announcement and patient query flow. use meshservice::{ capabilities, identity::ServiceIdentity, router::ServiceRouter, services::fapp::{create_announce, create_query, FappService, Modality, SlotAnnounce, SlotQuery, Specialism}, }; fn main() { println!("=== FAPP Service Demo ===\n"); // Create identities let therapist = ServiceIdentity::generate(); let patient = ServiceIdentity::generate(); let relay = ServiceIdentity::generate(); println!("Therapist address: {:?}", hex(&therapist.address())); println!("Patient address: {:?}", hex(&patient.address())); println!("Relay address: {:?}\n", hex(&relay.address())); // Create router with FAPP service let mut router = ServiceRouter::new(capabilities::RELAY); router.register(Box::new(FappService::relay())); // Therapist creates announcement let announce = SlotAnnounce::new( &[Specialism::CognitiveBehavioral, Specialism::TraumaFocused], Modality::VideoCall, "104", // Berlin Kreuzberg ) .with_slots(3) .with_profile("https://therapists.de/dr-schmidt") .with_name("Dr. Anna Schmidt"); println!("Therapist announces:"); println!(" Specialisms: CBT, Trauma"); println!(" Modality: Video"); println!(" Location: 104xx"); println!(" Slots: 3"); println!(" Profile: https://therapists.de/dr-schmidt\n"); let msg = create_announce(&therapist, &announce, 1).unwrap(); let action = router.handle(msg.clone(), Some(therapist.public_key())).unwrap(); println!("Router action: {:?}", action); println!("Stored messages: {}\n", router.store().len()); // Patient creates query let query = SlotQuery::new(Specialism::CognitiveBehavioral, "104") .with_modality(Modality::VideoCall) .with_max_wait(30); println!("Patient queries:"); println!(" Looking for: CBT"); println!(" Location: 104xx"); println!(" Modality: Video"); println!(" Max wait: 30 days\n"); let query_msg = create_query(&patient, &query).unwrap(); // Find matches let matches = router.query(&query_msg); println!("Found {} matching therapist(s):", matches.len()); for (i, m) in matches.iter().enumerate() { if let Ok(data) = meshservice::services::fapp::SlotAnnounce::from_bytes(&m.message.payload) { println!(" {}. {} in {}xx ({} slots)", i + 1, data.display_name.as_deref().unwrap_or("Unknown"), data.postal_prefix, data.available_slots ); if let Some(profile) = &data.profile_url { println!(" Verify: {}", profile); } } } println!("\n=== Demo Complete ==="); } fn hex(bytes: &[u8]) -> String { bytes.iter().map(|b| format!("{b:02x}")).collect() }