1use std::{marker::PhantomData, sync::Arc};
2
3use candid::{CandidType, Principal};
4use ic_cdk::management_canister::CanisterSettings;
5use pocket_ic::nonblocking::PocketIc;
6use serde::Deserialize;
7
8use crate::{CallBuilder, CallMode, Caller, DeployBuilder, DeployMode, Deployer};
9
10#[derive(Clone)]
11pub struct IcpUser {
12 pub principal: Principal,
13 pub(crate) pic: Arc<PocketIc>,
14}
15
16impl IcpUser {
17 pub fn call<ResultType>(
18 &self,
19 canister_id: Principal,
20 call_mode: CallMode,
21 method: &str,
22 args: Result<Vec<u8>, candid::error::Error>,
23 ) -> CallBuilder<ResultType, Self>
24 where
25 ResultType: for<'a> Deserialize<'a> + CandidType,
26 {
27 CallBuilder {
28 provider: self.clone(),
29 canister_id,
30 call_mode,
31 method: method.to_string(),
32 args,
33 _result: PhantomData,
34 }
35 }
36
37 pub fn deploy<Canister>(
38 &self,
39 args: Result<Vec<u8>, candid::error::Error>,
40 new: fn(&Self, Principal) -> Canister,
41 ) -> DeployBuilder<Canister, Self> {
42 DeployBuilder {
43 provider: self.clone(),
44 caller: self.clone(),
45 canister_id: None,
46 mode: DeployMode::Create,
47 settings: CanisterSettings::default(),
48 cycles: u64::MAX as u128,
49 wasm: vec![],
50 args,
51 new,
52 }
53 }
54}
55
56impl Caller for IcpUser {
57 type Provider = IcpUser;
58
59 fn call<ResultType>(
60 &self,
61 canister_id: Principal,
62 call_mode: CallMode,
63 method: &str,
64 args: Result<Vec<u8>, candid::error::Error>,
65 ) -> CallBuilder<ResultType, Self::Provider>
66 where
67 ResultType: for<'a> Deserialize<'a> + CandidType,
68 {
69 IcpUser::call(self, canister_id, call_mode, method, args)
70 }
71}
72
73impl Deployer for IcpUser {
74 type Caller = IcpUser;
75
76 fn deploy<Canister>(
77 &self,
78 args: Result<Vec<u8>, candid::error::Error>,
79 new: fn(&Self::Caller, Principal) -> Canister,
80 ) -> DeployBuilder<Canister, Self::Caller> {
81 IcpUser::deploy(self, args, new)
82 }
83}