hiero_sdk/file/
file_info.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use hiero_sdk_proto::services;
4use time::{
5    Duration,
6    OffsetDateTime,
7};
8
9use crate::protobuf::ToProtobuf;
10use crate::{
11    AccountId,
12    FileId,
13    FromProtobuf,
14    KeyList,
15    LedgerId,
16};
17
18/// Response from [`FileInfoQuery`][crate::FileInfoQuery].
19#[derive(Debug, Clone)]
20pub struct FileInfo {
21    /// The file ID of the file for which information is requested.
22    pub file_id: FileId,
23
24    /// Number of bytes in contents.
25    pub size: u64,
26
27    /// Current time which this account is set to expire.
28    pub expiration_time: Option<OffsetDateTime>,
29
30    /// The auto renew period for this file.
31    ///
32    /// # Network Support
33    /// Please note that this not supported on any hedera network at this time.
34    pub auto_renew_period: Option<Duration>,
35
36    /// The account to be used at this file's expiration time to extend the
37    /// life of the file.
38    ///
39    /// # Network Support
40    /// Please note that this not supported on any hedera network at this time.
41    pub auto_renew_account_id: Option<AccountId>,
42
43    /// True if deleted but not yet expired.
44    pub is_deleted: bool,
45
46    /// One of these keys must sign in order to modify or delete the file.
47    pub keys: KeyList,
48
49    /// Memo associated with the file.
50    pub file_memo: String,
51
52    /// Ledger ID for the network the response was returned from.
53    pub ledger_id: LedgerId,
54}
55
56impl FileInfo {
57    /// Create a new `FileInfo` from protobuf-encoded `bytes`.
58    ///
59    /// # Errors
60    /// - [`Error::FromProtobuf`](crate::Error::FromProtobuf) if decoding the bytes fails to produce a valid protobuf.
61    /// - [`Error::FromProtobuf`](crate::Error::FromProtobuf) if decoding the protobuf fails.
62    pub fn from_bytes(bytes: &[u8]) -> crate::Result<Self> {
63        FromProtobuf::<services::file_get_info_response::FileInfo>::from_bytes(bytes)
64    }
65
66    /// Convert `self` to a protobuf-encoded [`Vec<u8>`].
67    #[must_use]
68    pub fn to_bytes(&self) -> Vec<u8> {
69        ToProtobuf::to_bytes(self)
70    }
71}
72
73impl FromProtobuf<services::response::Response> for FileInfo {
74    #[allow(deprecated)]
75    fn from_protobuf(pb: services::response::Response) -> crate::Result<Self>
76    where
77        Self: Sized,
78    {
79        let response = pb_getv!(pb, FileGetInfo, services::response::Response);
80        let info = pb_getf!(response, file_info)?;
81        Self::from_protobuf(info)
82    }
83}
84
85impl FromProtobuf<services::file_get_info_response::FileInfo> for FileInfo {
86    #[allow(deprecated)]
87    fn from_protobuf(pb: services::file_get_info_response::FileInfo) -> crate::Result<Self>
88    where
89        Self: Sized,
90    {
91        let file_id = pb_getf!(pb, file_id)?;
92        let ledger_id = LedgerId::from_bytes(pb.ledger_id);
93
94        Ok(Self {
95            file_id: FileId::from_protobuf(file_id)?,
96            size: pb.size as u64,
97            expiration_time: pb.expiration_time.map(Into::into),
98            auto_renew_account_id: None,
99            auto_renew_period: None,
100            is_deleted: pb.deleted,
101            file_memo: pb.memo,
102            ledger_id,
103            keys: KeyList::from_protobuf(pb.keys.unwrap_or_default())?,
104        })
105    }
106}
107
108impl ToProtobuf for FileInfo {
109    type Protobuf = services::file_get_info_response::FileInfo;
110
111    fn to_protobuf(&self) -> Self::Protobuf {
112        services::file_get_info_response::FileInfo {
113            file_id: Some(self.file_id.to_protobuf()),
114            size: self.size as i64,
115            expiration_time: self.expiration_time.to_protobuf(),
116            deleted: self.is_deleted,
117            memo: self.file_memo.clone(),
118            ledger_id: self.ledger_id.to_bytes(),
119            keys: Some(self.keys.to_protobuf()),
120        }
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use expect_test::expect;
127    use hiero_sdk_proto::services;
128    use prost::Message;
129
130    use crate::protobuf::{
131        FromProtobuf,
132        ToProtobuf,
133    };
134    use crate::transaction::test_helpers::unused_private_key;
135    use crate::{
136        FileInfo,
137        Key,
138        LedgerId,
139    };
140
141    fn make_info() -> services::file_get_info_response::FileInfo {
142        services::file_get_info_response::FileInfo {
143            file_id: Some(services::FileId { shard_num: 0, realm_num: 0, file_num: 1 }),
144            size: 2,
145            expiration_time: Some(services::Timestamp { seconds: 0, nanos: 3_000 }),
146            deleted: true,
147            keys: Some(services::KeyList {
148                keys: Vec::from([Key::from(unused_private_key().public_key()).to_protobuf()]),
149            }),
150            ledger_id: LedgerId::mainnet().to_bytes(),
151
152            ..Default::default()
153        }
154    }
155
156    #[test]
157    fn from_protobuf() {
158        expect![[r#"
159            FileInfo {
160                file_id: "0.0.1",
161                size: 2,
162                expiration_time: Some(
163                    1970-01-01 0:00:00.000003 +00:00:00,
164                ),
165                auto_renew_period: None,
166                auto_renew_account_id: None,
167                is_deleted: true,
168                keys: KeyList {
169                    keys: [
170                        Single(
171                            "302a300506032b6570032100e0c8ec2758a5879ffac226a13c0c516b799e72e35141a0dd828f94d37988a4b7",
172                        ),
173                    ],
174                    threshold: None,
175                },
176                file_memo: "",
177                ledger_id: "mainnet",
178            }
179        "#]].assert_debug_eq(&FileInfo::from_protobuf(make_info()).unwrap());
180    }
181
182    #[test]
183    fn to_protobuf() {
184        expect![[r#"
185            FileInfo {
186                file_id: Some(
187                    FileId {
188                        shard_num: 0,
189                        realm_num: 0,
190                        file_num: 1,
191                    },
192                ),
193                size: 2,
194                expiration_time: Some(
195                    Timestamp {
196                        seconds: 0,
197                        nanos: 3000,
198                    },
199                ),
200                deleted: true,
201                keys: Some(
202                    KeyList {
203                        keys: [
204                            Key {
205                                key: Some(
206                                    Ed25519(
207                                        [
208                                            224,
209                                            200,
210                                            236,
211                                            39,
212                                            88,
213                                            165,
214                                            135,
215                                            159,
216                                            250,
217                                            194,
218                                            38,
219                                            161,
220                                            60,
221                                            12,
222                                            81,
223                                            107,
224                                            121,
225                                            158,
226                                            114,
227                                            227,
228                                            81,
229                                            65,
230                                            160,
231                                            221,
232                                            130,
233                                            143,
234                                            148,
235                                            211,
236                                            121,
237                                            136,
238                                            164,
239                                            183,
240                                        ],
241                                    ),
242                                ),
243                            },
244                        ],
245                    },
246                ),
247                memo: "",
248                ledger_id: [
249                    0,
250                ],
251            }
252        "#]]
253        .assert_debug_eq(&FileInfo::from_protobuf(make_info()).unwrap().to_protobuf());
254    }
255
256    #[test]
257    fn from_bytes() {
258        expect![[r#"
259            FileInfo {
260                file_id: "0.0.1",
261                size: 2,
262                expiration_time: Some(
263                    1970-01-01 0:00:00.000003 +00:00:00,
264                ),
265                auto_renew_period: None,
266                auto_renew_account_id: None,
267                is_deleted: true,
268                keys: KeyList {
269                    keys: [
270                        Single(
271                            "302a300506032b6570032100e0c8ec2758a5879ffac226a13c0c516b799e72e35141a0dd828f94d37988a4b7",
272                        ),
273                    ],
274                    threshold: None,
275                },
276                file_memo: "",
277                ledger_id: "mainnet",
278            }
279        "#]].assert_debug_eq(&FileInfo::from_bytes(&make_info().encode_to_vec()).unwrap());
280    }
281}