use candid::{CandidType, Principal, decode_one, encode_args, utils::ArgumentEncoder};
use serde::de::DeserializeOwned;
use super::{Pic, PicCallError};
impl Pic {
pub fn update_call<T, A>(
&self,
canister_id: Principal,
method: &str,
args: A,
) -> Result<T, PicCallError>
where
T: CandidType + DeserializeOwned,
A: ArgumentEncoder,
{
self.update_call_as(canister_id, Principal::anonymous(), method, args)
}
pub fn update_call_as<T, A>(
&self,
canister_id: Principal,
caller: Principal,
method: &str,
args: A,
) -> Result<T, PicCallError>
where
T: CandidType + DeserializeOwned,
A: ArgumentEncoder,
{
let bytes = encode_call_args(args)?;
let result = self
.inner
.update_call(canister_id, caller, method, bytes)
.map_err(|err| {
PicCallError::new(format!(
"pocket_ic update_call failed (canister={canister_id}, method={method}): {err}"
))
})?;
decode_call_result(&result)
}
pub fn query_call<T, A>(
&self,
canister_id: Principal,
method: &str,
args: A,
) -> Result<T, PicCallError>
where
T: CandidType + DeserializeOwned,
A: ArgumentEncoder,
{
self.query_call_as(canister_id, Principal::anonymous(), method, args)
}
pub fn query_call_as<T, A>(
&self,
canister_id: Principal,
caller: Principal,
method: &str,
args: A,
) -> Result<T, PicCallError>
where
T: CandidType + DeserializeOwned,
A: ArgumentEncoder,
{
let bytes = encode_call_args(args)?;
let result = self
.inner
.query_call(canister_id, caller, method, bytes)
.map_err(|err| {
PicCallError::new(format!(
"pocket_ic query_call failed (canister={canister_id}, method={method}): {err}"
))
})?;
decode_call_result(&result)
}
pub fn tick_n(&self, times: usize) {
for _ in 0..times {
self.tick();
}
}
}
fn encode_call_args<A>(args: A) -> Result<Vec<u8>, PicCallError>
where
A: ArgumentEncoder,
{
encode_args(args).map_err(|err| PicCallError::new(format!("encode_args failed: {err}")))
}
fn decode_call_result<T>(result: &[u8]) -> Result<T, PicCallError>
where
T: CandidType + DeserializeOwned,
{
decode_one(result).map_err(|err| PicCallError::new(format!("decode_one failed: {err}")))
}