hiero_sdk/system/
system_undelete_transaction.rs1use hiero_sdk_proto::services;
4use hiero_sdk_proto::services::file_service_client::FileServiceClient;
5use hiero_sdk_proto::services::smart_contract_service_client::SmartContractServiceClient;
6use tonic::transport::Channel;
7
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 ContractId,
23 Error,
24 FileId,
25 Transaction,
26 ValidateChecksums,
27};
28
29pub type SystemUndeleteTransaction = Transaction<SystemUndeleteTransactionData>;
31
32#[derive(Debug, Clone, Default)]
34pub struct SystemUndeleteTransactionData {
35 file_id: Option<FileId>,
36 contract_id: Option<ContractId>,
37}
38
39impl SystemUndeleteTransaction {
40 #[must_use]
42 pub fn get_contract_id(&self) -> Option<ContractId> {
43 self.data().contract_id
44 }
45
46 pub fn contract_id(&mut self, id: impl Into<ContractId>) -> &mut Self {
48 let data = self.data_mut();
49 data.file_id = None;
50 data.contract_id = Some(id.into());
51 self
52 }
53
54 #[must_use]
56 pub fn get_file_id(&self) -> Option<FileId> {
57 self.data().file_id
58 }
59
60 pub fn file_id(&mut self, id: impl Into<FileId>) -> &mut Self {
62 let data = self.data_mut();
63 data.contract_id = None;
64 data.file_id = Some(id.into());
65 self
66 }
67}
68
69impl TransactionData for SystemUndeleteTransactionData {}
70
71impl TransactionExecute for SystemUndeleteTransactionData {
72 #[allow(deprecated)]
73 fn execute(
74 &self,
75 channel: Channel,
76 request: services::Transaction,
77 ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
78 Box::pin(async move {
79 if self.file_id.is_some() {
80 FileServiceClient::new(channel).system_undelete(request).await
81 } else {
82 SmartContractServiceClient::new(channel).system_undelete(request).await
83 }
84 })
85 }
86}
87
88impl ValidateChecksums for SystemUndeleteTransactionData {
89 fn validate_checksums(&self, ledger_id: &crate::ledger_id::RefLedgerId) -> Result<(), Error> {
90 self.contract_id.validate_checksums(ledger_id)?;
91 self.file_id.validate_checksums(ledger_id)
92 }
93}
94
95impl ToTransactionDataProtobuf for SystemUndeleteTransactionData {
96 fn to_transaction_data_protobuf(
97 &self,
98 chunk_info: &ChunkInfo,
99 ) -> services::transaction_body::Data {
100 let _ = chunk_info.assert_single_transaction();
101
102 services::transaction_body::Data::SystemUndelete(self.to_protobuf())
103 }
104}
105
106impl ToSchedulableTransactionDataProtobuf for SystemUndeleteTransactionData {
107 fn to_schedulable_transaction_data_protobuf(
108 &self,
109 ) -> services::schedulable_transaction_body::Data {
110 services::schedulable_transaction_body::Data::SystemUndelete(self.to_protobuf())
111 }
112}
113
114impl From<SystemUndeleteTransactionData> for AnyTransactionData {
115 fn from(transaction: SystemUndeleteTransactionData) -> Self {
116 Self::SystemUndelete(transaction)
117 }
118}
119
120impl FromProtobuf<services::SystemUndeleteTransactionBody> for SystemUndeleteTransactionData {
121 fn from_protobuf(pb: services::SystemUndeleteTransactionBody) -> crate::Result<Self> {
122 use services::system_undelete_transaction_body::Id;
123 let (file_id, contract_id) = match pb.id {
124 Some(Id::FileId(it)) => (Some(FileId::from_protobuf(it)?), None),
125 Some(Id::ContractId(it)) => (None, Some(ContractId::from_protobuf(it)?)),
126 None => (None, None),
127 };
128
129 Ok(Self { file_id, contract_id })
130 }
131}
132
133impl ToProtobuf for SystemUndeleteTransactionData {
134 type Protobuf = services::SystemUndeleteTransactionBody;
135
136 fn to_protobuf(&self) -> Self::Protobuf {
137 let contract_id = self.contract_id.to_protobuf();
138 let file_id = self.file_id.to_protobuf();
139
140 let id = match (contract_id, file_id) {
141 (Some(contract_id), _) => {
142 Some(services::system_undelete_transaction_body::Id::ContractId(contract_id))
143 }
144
145 (_, Some(file_id)) => {
146 Some(services::system_undelete_transaction_body::Id::FileId(file_id))
147 }
148
149 _ => None,
150 };
151 services::SystemUndeleteTransactionBody { id }
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use expect_test::expect;
158 use hiero_sdk_proto::services;
159
160 use crate::protobuf::{
161 FromProtobuf,
162 ToProtobuf,
163 };
164 use crate::system::SystemUndeleteTransactionData;
165 use crate::transaction::test_helpers::{
166 check_body,
167 transaction_body,
168 };
169 use crate::{
170 AnyTransaction,
171 ContractId,
172 FileId,
173 SystemUndeleteTransaction,
174 };
175
176 const FILE_ID: FileId = FileId::new(0, 0, 444);
177 const CONTRACT_ID: ContractId = ContractId::new(0, 0, 444);
178
179 fn make_transaction_file() -> SystemUndeleteTransaction {
180 let mut tx = SystemUndeleteTransaction::new_for_tests();
181
182 tx.file_id(FILE_ID).freeze().unwrap();
183 tx
184 }
185
186 fn make_transaction_contract() -> SystemUndeleteTransaction {
187 let mut tx = SystemUndeleteTransaction::new_for_tests();
188
189 tx.contract_id(CONTRACT_ID).freeze().unwrap();
190 tx
191 }
192
193 #[test]
194 fn serialize_file() {
195 let tx = make_transaction_file();
196
197 let tx = transaction_body(tx);
198
199 let tx = check_body(tx);
200
201 expect![[r#"
202 SystemUndelete(
203 SystemUndeleteTransactionBody {
204 id: Some(
205 FileId(
206 FileId {
207 shard_num: 0,
208 realm_num: 0,
209 file_num: 444,
210 },
211 ),
212 ),
213 },
214 )
215 "#]]
216 .assert_debug_eq(&tx)
217 }
218
219 #[test]
220 fn serialize_contract() {
221 let tx = make_transaction_contract();
222
223 let tx = transaction_body(tx);
224
225 let tx = check_body(tx);
226
227 expect![[r#"
228 SystemUndelete(
229 SystemUndeleteTransactionBody {
230 id: Some(
231 ContractId(
232 ContractId {
233 shard_num: 0,
234 realm_num: 0,
235 contract: Some(
236 ContractNum(
237 444,
238 ),
239 ),
240 },
241 ),
242 ),
243 },
244 )
245 "#]]
246 .assert_debug_eq(&tx)
247 }
248
249 #[test]
250 fn to_from_bytes_file() {
251 let tx = make_transaction_file();
252
253 let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
254
255 let tx = transaction_body(tx);
256
257 let tx2 = transaction_body(tx2);
258
259 assert_eq!(tx, tx2);
260 }
261
262 #[test]
263 fn to_from_bytes_contract() {
264 let tx = make_transaction_contract();
265
266 let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
267
268 let tx = transaction_body(tx);
269
270 let tx2 = transaction_body(tx2);
271
272 assert_eq!(tx, tx2);
273 }
274
275 #[test]
276 fn from_proto_body() {
277 let tx = services::SystemUndeleteTransactionBody {
278 id: Some(services::system_undelete_transaction_body::Id::FileId(FILE_ID.to_protobuf())),
279 };
280
281 let tx = SystemUndeleteTransactionData::from_protobuf(tx).unwrap();
282
283 assert_eq!(tx.file_id, Some(FILE_ID));
284 assert_eq!(tx.contract_id, None);
285 }
286
287 #[test]
288 fn get_set_file_id() {
289 let mut tx = SystemUndeleteTransaction::new();
290 tx.file_id(FILE_ID);
291
292 assert_eq!(tx.get_file_id(), Some(FILE_ID));
293 }
294
295 #[test]
296 #[should_panic]
297 fn get_set_file_id_frozen_panics() {
298 make_transaction_file().file_id(FILE_ID);
299 }
300
301 #[test]
302 fn get_set_contract_id() {
303 let mut tx = SystemUndeleteTransaction::new();
304 tx.contract_id(CONTRACT_ID);
305
306 assert_eq!(tx.get_contract_id(), Some(CONTRACT_ID));
307 }
308
309 #[test]
310 #[should_panic]
311 fn get_set_contract_id_frozen_panics() {
312 make_transaction_file().contract_id(CONTRACT_ID);
313 }
314}