1use rs_zephyr_common::{wrapping::WrappedMaxBytes, ContractDataEntry};
2use soroban_sdk::{Map, TryFromVal, Val};
3use stellar_xdr::next::{Limits, ScVal, WriteXdr};
4use crate::{env::EnvClient, external::{read_contract_data_entry_by_contract_id_and_key, read_contract_entries_by_contract, read_contract_entries_by_contract_to_env, read_contract_instance}, SdkError};
5
6
7impl EnvClient {
8 fn express_and_deser_entry(status: i64, offset: i64, size: i64) -> Result<Option<ContractDataEntry>, SdkError> {
9 SdkError::express_from_status(status)?;
10
11 let memory: *const u8 = offset as *const u8;
12 let slice = unsafe { core::slice::from_raw_parts(memory, size as usize) };
13
14 bincode::deserialize::<Option<ContractDataEntry>>(slice).map_err(|_| SdkError::Conversion)
15 }
16
17 pub fn read_contract_instance(&self, contract: [u8; 32]) -> Result<Option<ContractDataEntry>, SdkError> {
20 let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
21 let (status, offset, size) = unsafe { read_contract_instance(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3]) };
22
23 Self::express_and_deser_entry(status, offset, size)
24 }
25
26 pub fn read_contract_entry_by_key(&self, contract: [u8; 32], key: ScVal) -> Result<Option<ContractDataEntry>, SdkError> {
29 let key_bytes = key.to_xdr(Limits::none()).unwrap();
30 let (offset, size) = (key_bytes.as_ptr() as i64, key_bytes.len() as i64);
31
32 let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
33 let (status, inbound_offset, inbound_size) = unsafe {
34 read_contract_data_entry_by_contract_id_and_key(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3], offset, size)
35 };
36
37 Self::express_and_deser_entry(status, inbound_offset, inbound_size)
38 }
39
40 pub fn read_contract_entries(&self, contract: [u8; 32]) -> Result<Vec<ContractDataEntry>, SdkError> {
43 let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
44
45 let (status, offset, size) = unsafe { read_contract_entries_by_contract(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3]) };
46
47 SdkError::express_from_status(status)?;
48
49 let memory: *const u8 = offset as *const u8;
50 let slice = unsafe { core::slice::from_raw_parts(memory, size as usize) };
51
52 bincode::deserialize::<Vec<ContractDataEntry>>(slice).map_err(|_| SdkError::Conversion)
53 }
54
55 pub fn read_contract_entries_to_env(&self, env: &soroban_sdk::Env, contract: [u8; 32]) -> Result<Map<Val, Val>, SdkError> {
60 let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
61 let (status, mapobject ) = unsafe { read_contract_entries_by_contract_to_env(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3]) };
62 SdkError::express_from_status(status)?;
63
64 let map = Map::try_from_val(env, &Val::from_payload(mapobject as u64)).unwrap();
65 Ok(map)
66 }
67}