multiversx_sc_scenario/scenario/model/account_data/
account_check.rs1use multiversx_sc::codec::{top_encode_to_vec_u8_or_panic, TopEncode};
2
3use crate::{
4 scenario::model::{
5 BigUintValue, BytesKey, BytesValue, CheckEsdt, CheckEsdtInstances, CheckEsdtMap,
6 CheckEsdtMapContents, CheckStorage, CheckStorageDetails, CheckValue, U64Value,
7 },
8 scenario_format::{
9 interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw},
10 serde_raw::CheckAccountRaw,
11 },
12 scenario_model::CheckEsdtData,
13};
14use std::collections::BTreeMap;
15
16#[derive(Debug, Default, Clone)]
17pub struct CheckAccount {
18 pub comment: Option<String>,
19 pub nonce: CheckValue<U64Value>,
20 pub balance: CheckValue<BigUintValue>,
21 pub esdt: CheckEsdtMap,
22 pub username: CheckValue<BytesValue>,
23 pub storage: CheckStorage,
24 pub code: CheckValue<BytesValue>,
25 pub code_metadata: CheckValue<BytesValue>,
26 pub owner: CheckValue<BytesValue>, pub developer_rewards: CheckValue<BigUintValue>,
28 pub async_call_data: CheckValue<BytesValue>,
29}
30
31impl CheckAccount {
32 pub fn new() -> Self {
33 Self::default()
34 }
35
36 pub fn nonce<V>(mut self, nonce: V) -> Self
37 where
38 U64Value: InterpretableFrom<V>,
39 {
40 self.nonce = CheckValue::Equal(U64Value::interpret_from(
41 nonce,
42 &InterpreterContext::default(),
43 ));
44 self
45 }
46
47 pub fn balance<V>(mut self, balance_expr: V) -> Self
48 where
49 BigUintValue: InterpretableFrom<V>,
50 {
51 self.balance = CheckValue::Equal(BigUintValue::interpret_from(
52 balance_expr,
53 &InterpreterContext::default(),
54 ));
55 self
56 }
57
58 pub fn code<V>(mut self, code_expr: V) -> Self
59 where
60 BytesValue: InterpretableFrom<V>,
61 {
62 self.code = CheckValue::Equal(BytesValue::interpret_from(
63 code_expr,
64 &InterpreterContext::default(),
65 ));
66 self
67 }
68
69 pub fn code_metadata<V>(mut self, code_metadata_expr: V) -> Self
70 where
71 BytesValue: InterpretableFrom<V>,
72 {
73 self.code_metadata = CheckValue::Equal(BytesValue::interpret_from(
74 code_metadata_expr,
75 &InterpreterContext::default(),
76 ));
77 self
78 }
79
80 pub fn esdt_balance<K, V>(mut self, token_id_expr: K, balance_expr: V) -> Self
81 where
82 BytesKey: From<K>,
83 BigUintValue: From<V>,
84 {
85 let token_id = BytesKey::from(token_id_expr);
86 let balance = BigUintValue::from(balance_expr);
87
88 match &mut self.esdt {
89 CheckEsdtMap::Unspecified | CheckEsdtMap::Star => {
90 let mut new_esdt_map = BTreeMap::new();
91 let _ = new_esdt_map.insert(token_id, CheckEsdt::Short(balance));
92
93 let new_check_esdt_map = CheckEsdtMapContents {
94 contents: new_esdt_map,
95 other_esdts_allowed: true,
96 };
97
98 self.esdt = CheckEsdtMap::Equal(new_check_esdt_map);
99 }
100 CheckEsdtMap::Equal(check_esdt_map) => {
101 if check_esdt_map.contents.contains_key(&token_id) {
102 let prev_entry = check_esdt_map.contents.get_mut(&token_id).unwrap();
103 match prev_entry {
104 CheckEsdt::Short(prev_balance_check) => *prev_balance_check = balance,
105 CheckEsdt::Full(prev_esdt_check) => match prev_esdt_check.instances {
106 CheckEsdtInstances::Star => todo!(),
107 CheckEsdtInstances::Equal(_) => todo!(),
108 },
109 }
110 }
111 }
112 }
113
114 self
115 }
116
117 pub fn esdt_nft_balance_and_attributes<K, N, V, T>(
118 mut self,
119 token_id_expr: K,
120 nonce_expr: N,
121 balance_expr: V,
122 attributes_expr: Option<T>,
123 ) -> Self
124 where
125 BytesKey: From<K>,
126 U64Value: From<N>,
127 BigUintValue: From<V>,
128 T: TopEncode,
129 {
130 let token_id = BytesKey::from(token_id_expr);
131
132 if let CheckEsdtMap::Unspecified = &self.esdt {
133 let mut check_esdt = CheckEsdt::Full(CheckEsdtData::default());
134
135 if let Some(attributes_expr) = attributes_expr {
136 check_esdt.add_balance_and_attributes_check(
137 nonce_expr,
138 balance_expr,
139 top_encode_to_vec_u8_or_panic(&attributes_expr),
140 );
141 } else {
142 check_esdt.add_balance_and_attributes_check(
143 nonce_expr,
144 balance_expr,
145 Vec::<u8>::new(),
146 );
147 }
148
149 let mut new_esdt_map = BTreeMap::new();
150 let _ = new_esdt_map.insert(token_id, check_esdt);
151
152 let new_check_esdt_map = CheckEsdtMapContents {
153 contents: new_esdt_map,
154 other_esdts_allowed: true,
155 };
156
157 self.esdt = CheckEsdtMap::Equal(new_check_esdt_map);
158 }
159
160 self
161 }
162
163 pub fn check_storage(mut self, key: &str, value: &str) -> Self {
164 let mut details = match self.storage {
165 CheckStorage::Star => CheckStorageDetails::default(),
166 CheckStorage::Equal(details) => details,
167 };
168 details.storages.insert(
169 BytesKey::interpret_from(key, &InterpreterContext::default()),
170 CheckValue::Equal(BytesValue::interpret_from(
171 value,
172 &InterpreterContext::default(),
173 )),
174 );
175 self.storage = CheckStorage::Equal(details);
176 self
177 }
178}
179
180impl InterpretableFrom<Box<CheckAccountRaw>> for CheckAccount {
181 fn interpret_from(from: Box<CheckAccountRaw>, context: &InterpreterContext) -> Self {
182 CheckAccount {
183 comment: from.comment,
184 nonce: CheckValue::<U64Value>::interpret_from(from.nonce, context),
185 balance: CheckValue::<BigUintValue>::interpret_from(from.balance, context),
186 esdt: CheckEsdtMap::interpret_from(from.esdt, context),
187 username: CheckValue::<BytesValue>::interpret_from(from.username, context),
188 storage: CheckStorage::interpret_from(from.storage, context),
189 code: CheckValue::<BytesValue>::interpret_from(from.code, context),
190 code_metadata: CheckValue::<BytesValue>::interpret_from(from.code_metadata, context),
191 owner: CheckValue::<BytesValue>::interpret_from(from.owner, context),
192 developer_rewards: CheckValue::<BigUintValue>::interpret_from(
193 from.developer_rewards,
194 context,
195 ),
196 async_call_data: CheckValue::<BytesValue>::interpret_from(
197 from.async_call_data,
198 context,
199 ),
200 }
201 }
202}
203
204impl IntoRaw<CheckAccountRaw> for CheckAccount {
205 fn into_raw(self) -> CheckAccountRaw {
206 CheckAccountRaw {
207 comment: self.comment,
208 nonce: self.nonce.into_raw(),
209 balance: self.balance.into_raw(),
210 esdt: self.esdt.into_raw(),
211 username: self.username.into_raw(),
212 storage: self.storage.into_raw(),
213 code: self.code.into_raw_explicit(), code_metadata: self.code_metadata.into_raw(),
215 owner: self.owner.into_raw_explicit(), developer_rewards: self.developer_rewards.into_raw(),
217 async_call_data: self.async_call_data.into_raw(),
218 }
219 }
220}