diff --git a/contracts/hospital-registry/src/lib.rs b/contracts/hospital-registry/src/lib.rs index cd2d853..0edf140 100644 --- a/contracts/hospital-registry/src/lib.rs +++ b/contracts/hospital-registry/src/lib.rs @@ -1,7 +1,18 @@ #![no_std] #![allow(deprecated)] -use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Address, Env, String, Vec}; +use soroban_sdk::{ + contract, contracterror, contractimpl, contracttype, symbol_short, Address, Env, String, Vec, +}; + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum ContractError { + HospitalAlreadyRegistered = 1, + HospitalNotFound = 2, + HospitalConfigNotFound = 3, +} /// -------------------- /// Hospital Structures @@ -112,11 +123,12 @@ pub struct HospitalRegistry; #[contractimpl] impl HospitalRegistry { - fn assert_hospital_exists(env: &Env, wallet: &Address) { + fn assert_hospital_exists(env: &Env, wallet: &Address) -> Result<(), ContractError> { let key = DataKey::Hospital(wallet.clone()); if !env.storage().persistent().has(&key) { - panic!("Hospital not found"); + return Err(ContractError::HospitalNotFound); } + Ok(()) } fn default_config(env: &Env) -> HospitalConfig { @@ -149,12 +161,12 @@ impl HospitalRegistry { name: String, location: String, metadata: String, - ) { + ) -> Result<(), ContractError> { wallet.require_auth(); let key = DataKey::Hospital(wallet.clone()); if env.storage().persistent().has(&key) { - panic!("Hospital already registered"); + return Err(ContractError::HospitalAlreadyRegistered); } let hospital = HospitalData { @@ -173,6 +185,7 @@ impl HospitalRegistry { (symbol_short!("reg_hosp"), wallet), symbol_short!("success"), ); + Ok(()) } /// Update hospital metadata @@ -180,7 +193,7 @@ impl HospitalRegistry { /// # Arguments /// * `wallet` - The wallet address of the hospital /// * `metadata` - Updated metadata information - pub fn update_hospital(env: Env, wallet: Address, metadata: String) { + pub fn update_hospital(env: Env, wallet: Address, metadata: String) -> Result<(), ContractError> { wallet.require_auth(); let key = DataKey::Hospital(wallet.clone()); @@ -188,7 +201,7 @@ impl HospitalRegistry { .storage() .persistent() .get(&key) - .expect("Hospital not found"); + .ok_or(ContractError::HospitalNotFound)?; hospital.metadata = metadata; env.storage().persistent().set(&key, &hospital); @@ -197,6 +210,7 @@ impl HospitalRegistry { (symbol_short!("upd_hosp"), wallet), symbol_short!("success"), ); + Ok(()) } /// Retrieve hospital data by wallet address @@ -206,45 +220,45 @@ impl HospitalRegistry { /// /// # Returns /// The HospitalData for the given wallet address - pub fn get_hospital(env: Env, wallet: Address) -> HospitalData { + pub fn get_hospital(env: Env, wallet: Address) -> Result { let key = DataKey::Hospital(wallet); env.storage() .persistent() .get(&key) - .expect("Hospital not found") + .ok_or(ContractError::HospitalNotFound) } /// Set full hospital configuration in one call - pub fn set_hospital_config(env: Env, wallet: Address, config: HospitalConfig) { + pub fn set_hospital_config(env: Env, wallet: Address, config: HospitalConfig) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); env.storage().persistent().set(&key, &config); env.events() .publish((symbol_short!("cfg_set"), wallet), symbol_short!("success")); + Ok(()) } - /// Retrieve hospital configuration - pub fn get_hospital_config(env: Env, wallet: Address) -> HospitalConfig { + pub fn get_hospital_config(env: Env, wallet: Address) -> Result { let key = DataKey::HospitalConfig(wallet); env.storage() .persistent() .get(&key) - .expect("Hospital config not found") + .ok_or(ContractError::HospitalConfigNotFound) } - pub fn update_departments(env: Env, wallet: Address, departments: Vec) { + pub fn update_departments(env: Env, wallet: Address, departments: Vec) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.departments = departments; env.storage().persistent().set(&key, &config); @@ -253,72 +267,76 @@ impl HospitalRegistry { (symbol_short!("upd_dept"), wallet), symbol_short!("success"), ); + Ok(()) } - pub fn update_locations(env: Env, wallet: Address, locations: Vec) { + pub fn update_locations(env: Env, wallet: Address, locations: Vec) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.locations = locations; env.storage().persistent().set(&key, &config); env.events() .publish((symbol_short!("upd_loc"), wallet), symbol_short!("success")); + Ok(()) } - pub fn update_equipment(env: Env, wallet: Address, equipment: Vec) { + pub fn update_equipment(env: Env, wallet: Address, equipment: Vec) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.equipment = equipment; env.storage().persistent().set(&key, &config); env.events() .publish((symbol_short!("upd_eq"), wallet), symbol_short!("success")); + Ok(()) } - pub fn update_policies(env: Env, wallet: Address, policies: Vec) { + pub fn update_policies(env: Env, wallet: Address, policies: Vec) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.policies = policies; env.storage().persistent().set(&key, &config); env.events() .publish((symbol_short!("upd_pol"), wallet), symbol_short!("success")); + Ok(()) } - pub fn update_alerts(env: Env, wallet: Address, alerts: Vec) { + pub fn update_alerts(env: Env, wallet: Address, alerts: Vec) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.alerts = alerts; env.storage().persistent().set(&key, &config); @@ -327,40 +345,42 @@ impl HospitalRegistry { (symbol_short!("upd_alrt"), wallet), symbol_short!("success"), ); + Ok(()) } pub fn update_insurance_providers( env: Env, wallet: Address, insurance_providers: Vec, - ) { + ) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.insurance_providers = insurance_providers; env.storage().persistent().set(&key, &config); env.events() .publish((symbol_short!("upd_ins"), wallet), symbol_short!("success")); + Ok(()) } - pub fn update_billing(env: Env, wallet: Address, billing: BillingConfig) { + pub fn update_billing(env: Env, wallet: Address, billing: BillingConfig) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.billing = billing; env.storage().persistent().set(&key, &config); @@ -369,28 +389,30 @@ impl HospitalRegistry { (symbol_short!("upd_bill"), wallet), symbol_short!("success"), ); + Ok(()) } pub fn update_emergency_protocols( env: Env, wallet: Address, protocols: Vec, - ) { + ) -> Result<(), ContractError> { wallet.require_auth(); - Self::assert_hospital_exists(&env, &wallet); + Self::assert_hospital_exists(&env, &wallet)?; let key = DataKey::HospitalConfig(wallet.clone()); let mut config: HospitalConfig = env .storage() .persistent() .get(&key) - .expect("Hospital config not found"); + .ok_or(ContractError::HospitalConfigNotFound)?; config.emergency_protocols = protocols; env.storage().persistent().set(&key, &config); env.events() .publish((symbol_short!("upd_emg"), wallet), symbol_short!("success")); + Ok(()) } } diff --git a/contracts/hospital-registry/src/test.rs b/contracts/hospital-registry/src/test.rs index 6522ff1..3a009f9 100644 --- a/contracts/hospital-registry/src/test.rs +++ b/contracts/hospital-registry/src/test.rs @@ -9,7 +9,6 @@ fn test_register_hospital() { let client = HospitalRegistryClient::new(&env, &contract_id); let hospital_wallet = Address::generate(&env); - env.mock_all_auths(); client.register_hospital( @@ -39,7 +38,6 @@ fn test_update_hospital() { let client = HospitalRegistryClient::new(&env, &contract_id); let hospital_wallet = Address::generate(&env); - env.mock_all_auths(); client.register_hospital( @@ -64,14 +62,12 @@ fn test_update_hospital() { } #[test] -#[should_panic(expected = "Hospital already registered")] fn test_duplicate_registration() { let env = Env::default(); let contract_id = env.register_contract(None, HospitalRegistry); let client = HospitalRegistryClient::new(&env, &contract_id); let hospital_wallet = Address::generate(&env); - env.mock_all_auths(); client.register_hospital( @@ -81,17 +77,17 @@ fn test_duplicate_registration() { &String::from_str(&env, "Test Metadata"), ); - // Attempt to register again - client.register_hospital( + let result = client.try_register_hospital( &hospital_wallet, &String::from_str(&env, "Test Hospital"), &String::from_str(&env, "Test Location"), &String::from_str(&env, "Test Metadata"), ); + + assert_eq!(result, Err(Ok(ContractError::HospitalAlreadyRegistered))); } #[test] -#[should_panic(expected = "Hospital not found")] fn test_get_nonexistent_hospital() { let env = Env::default(); let contract_id = env.register_contract(None, HospitalRegistry); @@ -99,24 +95,24 @@ fn test_get_nonexistent_hospital() { let hospital_wallet = Address::generate(&env); - client.get_hospital(&hospital_wallet); + let result = client.try_get_hospital(&hospital_wallet); + assert_eq!(result, Err(Ok(ContractError::HospitalNotFound))); } #[test] -#[should_panic(expected = "Hospital not found")] fn test_update_nonexistent_hospital() { let env = Env::default(); let contract_id = env.register_contract(None, HospitalRegistry); let client = HospitalRegistryClient::new(&env, &contract_id); let hospital_wallet = Address::generate(&env); - env.mock_all_auths(); - client.update_hospital( + let result = client.try_update_hospital( &hospital_wallet, &String::from_str(&env, "Updated Metadata"), ); + assert_eq!(result, Err(Ok(ContractError::HospitalNotFound))); } #[test]