hiero_sdk/token/
token_reject_transaction.rs1use hiero_sdk_proto::services;
4use hiero_sdk_proto::services::token_service_client::TokenServiceClient;
5use tonic::transport::Channel;
6
7use super::NftId;
8use crate::protobuf::{
9 FromProtobuf,
10 ToProtobuf,
11};
12use crate::transaction::{
13 AnyTransactionData,
14 ChunkInfo,
15 ToSchedulableTransactionDataProtobuf,
16 ToTransactionDataProtobuf,
17 TransactionData,
18 TransactionExecute,
19};
20use crate::{
21 AccountId,
22 BoxGrpcFuture,
23 Error,
24 TokenId,
25 Transaction,
26 ValidateChecksums,
27};
28
29pub type TokenRejectTransaction = Transaction<TokenRejectTransactionData>;
41
42#[derive(Debug, Clone, Default)]
43pub struct TokenRejectTransactionData {
44 owner: Option<AccountId>,
46
47 token_ids: Vec<TokenId>,
49
50 nft_ids: Vec<NftId>,
52}
53
54impl TokenRejectTransaction {
55 #[must_use]
57 pub fn get_owner(&self) -> Option<AccountId> {
58 self.data().owner
59 }
60
61 pub fn owner(&mut self, owner: impl Into<AccountId>) -> &mut Self {
63 self.data_mut().owner = Some(owner.into());
64 self
65 }
66
67 #[must_use]
69 pub fn get_token_ids(&self) -> Vec<TokenId> {
70 self.data().token_ids.clone()
71 }
72
73 pub fn token_ids(&mut self, token_ids: impl IntoIterator<Item = TokenId>) -> &mut Self {
75 self.data_mut().token_ids = token_ids.into_iter().collect();
76 self
77 }
78
79 pub fn add_token_id(&mut self, token_id: TokenId) -> &mut Self {
81 self.data_mut().token_ids.push(token_id);
82 self
83 }
84
85 #[must_use]
87 pub fn get_nft_ids(&self) -> Vec<NftId> {
88 self.data().nft_ids.clone()
89 }
90
91 pub fn nft_ids(&mut self, nft_ids: impl IntoIterator<Item = NftId>) -> &mut Self {
93 self.data_mut().nft_ids = nft_ids.into_iter().collect();
94 self
95 }
96
97 pub fn add_nft_id(&mut self, nft_id: NftId) -> &mut Self {
99 self.data_mut().nft_ids.push(nft_id);
100 self
101 }
102}
103
104impl TransactionData for TokenRejectTransactionData {}
105
106impl TransactionExecute for TokenRejectTransactionData {
107 fn execute(
108 &self,
109 channel: Channel,
110 request: services::Transaction,
111 ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
112 Box::pin(async { TokenServiceClient::new(channel).reject_token(request).await })
113 }
114}
115
116impl ValidateChecksums for TokenRejectTransactionData {
117 fn validate_checksums(&self, ledger_id: &crate::ledger_id::RefLedgerId) -> Result<(), Error> {
118 self.owner.validate_checksums(ledger_id)
119 }
120}
121
122impl ToTransactionDataProtobuf for TokenRejectTransactionData {
123 fn to_transaction_data_protobuf(
124 &self,
125 chunk_info: &ChunkInfo,
126 ) -> services::transaction_body::Data {
127 let _ = chunk_info.assert_single_transaction();
128
129 services::transaction_body::Data::TokenReject(self.to_protobuf())
130 }
131}
132
133impl ToSchedulableTransactionDataProtobuf for TokenRejectTransactionData {
134 fn to_schedulable_transaction_data_protobuf(
135 &self,
136 ) -> services::schedulable_transaction_body::Data {
137 services::schedulable_transaction_body::Data::TokenReject(self.to_protobuf())
138 }
139}
140
141impl From<TokenRejectTransactionData> for AnyTransactionData {
142 fn from(transaction: TokenRejectTransactionData) -> Self {
143 Self::TokenReject(transaction)
144 }
145}
146
147impl FromProtobuf<services::TokenRejectTransactionBody> for TokenRejectTransactionData {
148 fn from_protobuf(pb: services::TokenRejectTransactionBody) -> crate::Result<Self> {
149 let mut token_ids = Vec::new();
150 let mut nft_ids = Vec::new();
151
152 for reference in pb.rejections {
153 match reference.token_identifier {
154 Some(it) => match it {
155 services::token_reference::TokenIdentifier::FungibleToken(it) => {
156 token_ids.push(TokenId::from_protobuf(it)?);
157 }
158 services::token_reference::TokenIdentifier::Nft(it) => {
159 nft_ids.push(NftId::from_protobuf(it)?);
160 }
161 },
162 None => {
163 return Err(Error::from_protobuf("Invalid token identifier"));
164 }
165 }
166 }
167
168 Ok(Self { owner: Option::from_protobuf(pb.owner)?, token_ids, nft_ids })
169 }
170}
171
172impl ToProtobuf for TokenRejectTransactionData {
173 type Protobuf = services::TokenRejectTransactionBody;
174
175 fn to_protobuf(&self) -> Self::Protobuf {
176 let owner = self.owner.to_protobuf();
177
178 let rejections = self
179 .token_ids
180 .iter()
181 .map(|token_id| services::TokenReference {
182 token_identifier: Some(services::token_reference::TokenIdentifier::FungibleToken(
183 token_id.to_protobuf(),
184 )),
185 })
186 .chain(self.nft_ids.iter().map(|nft_id| services::TokenReference {
187 token_identifier: Some(services::token_reference::TokenIdentifier::Nft(
188 nft_id.to_protobuf(),
189 )),
190 }))
191 .collect::<Vec<_>>();
192
193 services::TokenRejectTransactionBody { owner, rejections }
194 }
195}
196
197#[cfg(test)]
198mod tests {
199
200 use expect_test::expect_file;
201 use hiero_sdk_proto::services::{
202 token_reference,
203 TokenReference,
204 TokenRejectTransactionBody,
205 };
206
207 use super::TokenRejectTransaction;
208 use crate::protobuf::{
209 FromProtobuf,
210 ToProtobuf,
211 };
212 use crate::token::TokenRejectTransactionData;
213 use crate::transaction::test_helpers::{
214 check_body,
215 transaction_body,
216 TEST_ACCOUNT_ID,
217 TEST_NFT_IDS,
218 TEST_TOKEN_IDS,
219 };
220 use crate::AnyTransaction;
221
222 fn make_transaction() -> TokenRejectTransaction {
223 let mut tx = TokenRejectTransaction::new_for_tests();
224 tx.owner(TEST_ACCOUNT_ID).token_ids(TEST_TOKEN_IDS).nft_ids(TEST_NFT_IDS).freeze().unwrap();
225
226 tx
227 }
228
229 #[test]
230 fn seriralize() {
231 let tx = make_transaction();
232
233 let tx = transaction_body(tx);
234
235 let tx = check_body(tx);
236
237 expect_file!["./snapshots/token_reject_transaction/serialize.txt"].assert_debug_eq(&tx);
238 }
239
240 #[test]
241 fn to_from_bytes() {
242 let tx = make_transaction();
243
244 let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
245
246 let tx = transaction_body(tx);
247 let tx2 = transaction_body(tx2);
248
249 assert_eq!(tx, tx2);
250 }
251
252 #[test]
253 fn from_proto_body() {
254 let mut references = Vec::new();
255
256 for token_id in TEST_TOKEN_IDS {
257 references.push(TokenReference {
258 token_identifier: Some(token_reference::TokenIdentifier::FungibleToken(
259 token_id.to_protobuf(),
260 )),
261 });
262 }
263
264 for nft_id in TEST_NFT_IDS {
265 references.push(TokenReference {
266 token_identifier: Some(token_reference::TokenIdentifier::Nft(nft_id.to_protobuf())),
267 });
268 }
269
270 let tx = TokenRejectTransactionBody {
271 owner: Some(TEST_ACCOUNT_ID.to_protobuf()),
272 rejections: references,
273 };
274
275 let data = TokenRejectTransactionData::from_protobuf(tx).unwrap();
276
277 assert_eq!(data.owner, Some(TEST_ACCOUNT_ID));
278 assert_eq!(data.token_ids, TEST_TOKEN_IDS);
279 assert_eq!(data.nft_ids, TEST_NFT_IDS);
280 }
281
282 #[test]
283 fn get_set_owner() {
284 let mut tx = TokenRejectTransaction::new();
285
286 let tx2 = tx.owner(TEST_ACCOUNT_ID);
287
288 assert_eq!(tx2.get_owner(), Some(TEST_ACCOUNT_ID));
289 }
290
291 #[test]
292 #[should_panic]
293 fn get_set_owner_frozen_panic() {
294 let mut tx = make_transaction();
295
296 tx.owner(TEST_ACCOUNT_ID);
297 }
298
299 #[test]
300 fn get_set_token_ids() {
301 let mut tx = TokenRejectTransaction::new();
302
303 let tx2 = tx.token_ids(TEST_TOKEN_IDS);
304
305 assert_eq!(tx2.get_token_ids(), TEST_TOKEN_IDS);
306 }
307
308 #[test]
309 #[should_panic]
310 fn get_set_token_ids_frozen_panic() {
311 let mut tx = make_transaction();
312
313 tx.token_ids(TEST_TOKEN_IDS);
314 }
315
316 #[test]
317 fn get_set_nft_ids() {
318 let mut tx = TokenRejectTransaction::new();
319
320 let tx2 = tx.nft_ids(TEST_NFT_IDS);
321
322 assert_eq!(tx2.get_nft_ids(), TEST_NFT_IDS);
323 }
324
325 #[test]
326 #[should_panic]
327 fn get_set_nft_ids_frozen_panic() {
328 let mut tx = make_transaction();
329
330 tx.nft_ids(TEST_NFT_IDS);
331 }
332
333 #[test]
334 fn get_set_add_token_ids() {
335 let mut tx = TokenRejectTransaction::new();
336
337 tx.add_token_id(TEST_TOKEN_IDS[0]);
338 tx.add_token_id(TEST_TOKEN_IDS[2]);
339
340 assert_eq!(tx.get_token_ids()[0], TEST_TOKEN_IDS[0]);
341 assert_eq!(tx.get_token_ids()[1], TEST_TOKEN_IDS[2]);
342 }
343
344 #[test]
345 fn get_set_add_nft_ids() {
346 let mut tx = TokenRejectTransaction::new();
347
348 tx.add_nft_id(TEST_NFT_IDS[0]);
349 tx.add_nft_id(TEST_NFT_IDS[2]);
350
351 assert_eq!(tx.get_nft_ids()[0], TEST_NFT_IDS[0]);
352 assert_eq!(tx.get_nft_ids()[1], TEST_NFT_IDS[2]);
353 }
354}