hiero_sdk/file/
file_delete_transaction.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use hiero_sdk_proto::services;
4use hiero_sdk_proto::services::file_service_client::FileServiceClient;
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    FileId,
24    Transaction,
25    ValidateChecksums,
26};
27
28/// Delete the given file.
29///
30/// After deletion, it will be marked as deleted and will have no contents.
31/// Information about it will continue to exist until it expires.
32///
33pub type FileDeleteTransaction = Transaction<FileDeleteTransactionData>;
34
35#[derive(Debug, Clone, Default)]
36pub struct FileDeleteTransactionData {
37    /// The file to delete. It will be marked as deleted until it expires.
38    /// Then it will disappear.
39    file_id: Option<FileId>,
40}
41
42impl FileDeleteTransaction {
43    /// Returns the ID of the file to be deleted.
44    #[must_use]
45    pub fn get_file_id(&self) -> Option<FileId> {
46        self.data().file_id
47    }
48
49    /// Sets the ID of the file to be deleted.
50    pub fn file_id(&mut self, id: impl Into<FileId>) -> &mut Self {
51        self.data_mut().file_id = Some(id.into());
52        self
53    }
54}
55
56impl TransactionData for FileDeleteTransactionData {}
57
58impl TransactionExecute for FileDeleteTransactionData {
59    fn execute(
60        &self,
61        channel: Channel,
62        request: services::Transaction,
63    ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
64        Box::pin(async { FileServiceClient::new(channel).delete_file(request).await })
65    }
66}
67
68impl ValidateChecksums for FileDeleteTransactionData {
69    fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
70        self.file_id.validate_checksums(ledger_id)
71    }
72}
73
74impl ToTransactionDataProtobuf for FileDeleteTransactionData {
75    fn to_transaction_data_protobuf(
76        &self,
77        chunk_info: &ChunkInfo,
78    ) -> services::transaction_body::Data {
79        let _ = chunk_info.assert_single_transaction();
80
81        services::transaction_body::Data::FileDelete(self.to_protobuf())
82    }
83}
84
85impl ToSchedulableTransactionDataProtobuf for FileDeleteTransactionData {
86    fn to_schedulable_transaction_data_protobuf(
87        &self,
88    ) -> services::schedulable_transaction_body::Data {
89        services::schedulable_transaction_body::Data::FileDelete(self.to_protobuf())
90    }
91}
92
93impl From<FileDeleteTransactionData> for AnyTransactionData {
94    fn from(transaction: FileDeleteTransactionData) -> Self {
95        Self::FileDelete(transaction)
96    }
97}
98
99impl FromProtobuf<services::FileDeleteTransactionBody> for FileDeleteTransactionData {
100    fn from_protobuf(pb: services::FileDeleteTransactionBody) -> crate::Result<Self> {
101        Ok(Self { file_id: Option::from_protobuf(pb.file_id)? })
102    }
103}
104
105impl ToProtobuf for FileDeleteTransactionData {
106    type Protobuf = services::FileDeleteTransactionBody;
107
108    fn to_protobuf(&self) -> Self::Protobuf {
109        services::FileDeleteTransactionBody { file_id: self.file_id.to_protobuf() }
110    }
111}
112
113#[cfg(test)]
114mod tests {
115    use expect_test::expect;
116    use hiero_sdk_proto::services;
117
118    use crate::file::FileDeleteTransactionData;
119    use crate::protobuf::{
120        FromProtobuf,
121        ToProtobuf,
122    };
123    use crate::transaction::test_helpers::{
124        check_body,
125        transaction_body,
126    };
127    use crate::{
128        AnyTransaction,
129        FileDeleteTransaction,
130        FileId,
131    };
132
133    const FILE_ID: FileId = FileId::new(0, 0, 6006);
134
135    fn make_transaction() -> FileDeleteTransaction {
136        let mut tx = FileDeleteTransaction::new_for_tests();
137
138        tx.file_id(FILE_ID).freeze().unwrap();
139
140        tx
141    }
142
143    #[test]
144    fn serialize() {
145        let tx = make_transaction();
146
147        let tx = transaction_body(tx);
148
149        let tx = check_body(tx);
150
151        expect![[r#"
152            FileDelete(
153                FileDeleteTransactionBody {
154                    file_id: Some(
155                        FileId {
156                            shard_num: 0,
157                            realm_num: 0,
158                            file_num: 6006,
159                        },
160                    ),
161                },
162            )
163        "#]]
164        .assert_debug_eq(&tx)
165    }
166
167    #[test]
168    fn to_from_bytes() {
169        let tx = make_transaction();
170
171        let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
172
173        let tx = transaction_body(tx);
174
175        let tx2 = transaction_body(tx2);
176
177        assert_eq!(tx, tx2);
178    }
179
180    #[test]
181    fn from_proto_body() {
182        let tx = services::FileDeleteTransactionBody { file_id: Some(FILE_ID.to_protobuf()) };
183
184        let tx = FileDeleteTransactionData::from_protobuf(tx).unwrap();
185
186        assert_eq!(tx.file_id, Some(FILE_ID));
187    }
188
189    #[test]
190    fn get_set_file_id() {
191        let mut tx = FileDeleteTransaction::new();
192        tx.file_id(FILE_ID);
193
194        assert_eq!(tx.get_file_id(), Some(FILE_ID));
195    }
196
197    #[test]
198    #[should_panic]
199    fn get_set_file_id_frozen_panics() {
200        make_transaction().file_id(FILE_ID);
201    }
202}