hiero_sdk/token/
token_update_nfts_transaction.rs1use hiero_sdk_proto::services;
4use hiero_sdk_proto::services::token_service_client::TokenServiceClient;
5use tonic::transport::Channel;
6
7use crate::ledger_id::RefLedgerId;
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 BoxGrpcFuture,
22 Error,
23 TokenId,
24 Transaction,
25 ValidateChecksums,
26};
27
28pub type TokenUpdateNftsTransaction = Transaction<TokenUpdateNftsTransactionData>;
37
38#[derive(Debug, Clone, Default)]
39pub struct TokenUpdateNftsTransactionData {
40 token_id: Option<TokenId>,
42
43 serials: Vec<i64>,
45
46 metadata: Vec<u8>,
48}
49
50impl TokenUpdateNftsTransaction {
51 #[must_use]
53 pub fn get_token_id(&self) -> Option<TokenId> {
54 self.data().token_id
55 }
56
57 pub fn token_id(&mut self, token_id: impl Into<TokenId>) -> &mut Self {
59 self.data_mut().token_id = Some(token_id.into());
60 self
61 }
62
63 #[must_use]
65 pub fn get_serials(&self) -> Vec<i64> {
66 self.data().serials.clone()
67 }
68
69 pub fn serials(&mut self, serials: Vec<i64>) -> &mut Self {
71 self.data_mut().serials = serials;
72 self
73 }
74
75 #[must_use]
77 pub fn get_metadata(&self) -> Vec<u8> {
78 self.data().metadata.clone()
79 }
80
81 pub fn metadata(&mut self, metadata: Vec<u8>) -> &mut Self {
83 self.data_mut().metadata = metadata;
84 self
85 }
86}
87
88impl TransactionData for TokenUpdateNftsTransactionData {}
89
90impl TransactionExecute for TokenUpdateNftsTransactionData {
91 fn execute(
92 &self,
93 channel: Channel,
94 request: services::Transaction,
95 ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
96 Box::pin(async { TokenServiceClient::new(channel).update_token(request).await })
97 }
98}
99
100impl ValidateChecksums for TokenUpdateNftsTransactionData {
101 fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
102 self.token_id.validate_checksums(ledger_id)
103 }
104}
105
106impl ToTransactionDataProtobuf for TokenUpdateNftsTransactionData {
107 fn to_transaction_data_protobuf(
108 &self,
109 chunk_info: &ChunkInfo,
110 ) -> services::transaction_body::Data {
111 let _ = chunk_info.assert_single_transaction();
112
113 services::transaction_body::Data::TokenUpdateNfts(self.to_protobuf())
114 }
115}
116
117impl ToSchedulableTransactionDataProtobuf for TokenUpdateNftsTransactionData {
118 fn to_schedulable_transaction_data_protobuf(
119 &self,
120 ) -> services::schedulable_transaction_body::Data {
121 services::schedulable_transaction_body::Data::TokenUpdateNfts(self.to_protobuf())
122 }
123}
124
125impl From<TokenUpdateNftsTransactionData> for AnyTransactionData {
126 fn from(transaction: TokenUpdateNftsTransactionData) -> Self {
127 Self::TokenUpdateNfts(transaction)
128 }
129}
130
131impl FromProtobuf<services::TokenUpdateNftsTransactionBody> for TokenUpdateNftsTransactionData {
132 fn from_protobuf(pb: services::TokenUpdateNftsTransactionBody) -> crate::Result<Self> {
133 Ok(Self {
134 token_id: Option::from_protobuf(pb.token)?,
135 serials: pb.serial_numbers,
136 metadata: pb.metadata.unwrap_or_default(),
137 })
138 }
139}
140
141impl ToProtobuf for TokenUpdateNftsTransactionData {
142 type Protobuf = services::TokenUpdateNftsTransactionBody;
143
144 fn to_protobuf(&self) -> Self::Protobuf {
145 services::TokenUpdateNftsTransactionBody {
146 token: self.token_id.to_protobuf(),
147 serial_numbers: self.serials.clone(),
148 metadata: Some(self.metadata.clone()),
149 }
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use expect_test::expect_file;
156 use hiero_sdk_proto::services;
157
158 use super::TokenUpdateNftsTransactionData;
159 use crate::protobuf::{
160 FromProtobuf,
161 ToProtobuf,
162 };
163 use crate::transaction::test_helpers::{
164 check_body,
165 transaction_body,
166 };
167 use crate::{
168 AnyTransaction,
169 TokenId,
170 TokenUpdateNftsTransaction,
171 };
172
173 const TEST_TOKEN_ID: TokenId = TokenId::new(0, 0, 12);
174 const TEST_METADATA: &str = "Token Metadata";
175
176 fn test_serials() -> Vec<i64> {
177 vec![1, 2, 3]
178 }
179
180 fn make_transaction() -> TokenUpdateNftsTransaction {
181 let mut tx = TokenUpdateNftsTransaction::new_for_tests();
182
183 tx.token_id(TEST_TOKEN_ID)
184 .serials(test_serials())
185 .metadata(TEST_METADATA.as_bytes().to_vec())
186 .freeze()
187 .unwrap();
188
189 tx
190 }
191
192 #[test]
193 fn serialize() {
194 let tx = make_transaction();
195
196 let tx = transaction_body(tx);
197
198 let tx = check_body(tx);
199
200 expect_file!["./snapshots/token_update_nfts_transaction/serialize.txt"]
201 .assert_debug_eq(&tx);
202 }
203
204 #[test]
205 fn to_from_bytes() {
206 let tx = make_transaction();
207
208 let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
209
210 let tx = transaction_body(tx);
211 let tx2 = transaction_body(tx2);
212
213 assert_eq!(tx, tx2);
214 }
215
216 #[test]
217 fn from_proto_body() {
218 let tx = services::TokenUpdateNftsTransactionBody {
219 token: Some(TEST_TOKEN_ID.to_protobuf()),
220 serial_numbers: test_serials(),
221 metadata: Some(TEST_METADATA.to_owned().into()),
222 };
223
224 let tx = TokenUpdateNftsTransactionData::from_protobuf(tx).unwrap();
225
226 assert_eq!(tx.token_id, Some(TEST_TOKEN_ID));
227 assert_eq!(tx.metadata, TEST_METADATA.as_bytes().to_vec());
228 assert_eq!(tx.serials, test_serials())
229 }
230
231 #[test]
232 fn get_set_token_id() {
233 let mut tx = TokenUpdateNftsTransaction::new();
234 tx.token_id(TEST_TOKEN_ID);
235 assert_eq!(tx.get_token_id(), Some(TEST_TOKEN_ID));
236 }
237
238 #[test]
239 #[should_panic]
240 fn get_set_token_id_frozen_panic() {
241 let mut tx = make_transaction();
242 tx.token_id(TEST_TOKEN_ID);
243 }
244
245 #[test]
246 fn get_set_metadata() {
247 let mut tx = TokenUpdateNftsTransaction::new();
248 tx.metadata(TEST_METADATA.as_bytes().to_vec());
249 assert_eq!(tx.get_metadata(), TEST_METADATA.as_bytes().to_vec());
250 }
251
252 #[test]
253 #[should_panic]
254 fn get_set_metadata_frozen_panic() {
255 let mut tx = make_transaction();
256 tx.metadata(TEST_METADATA.as_bytes().to_vec());
257 }
258
259 #[test]
260 fn get_set_serials() {
261 let mut tx = TokenUpdateNftsTransaction::new();
262 tx.serials(test_serials());
263 assert_eq!(tx.get_serials(), test_serials());
264 }
265
266 #[test]
267 #[should_panic]
268 fn get_set_serials_frozen_panic() {
269 let mut tx = make_transaction();
270 tx.serials(test_serials());
271 }
272}