1use std::fmt::{
4 self,
5 Debug,
6 Display,
7 Formatter,
8};
9use std::str::FromStr;
10
11use hiero_sdk_proto::services;
12
13use crate::entity_id::{
14 Checksum,
15 ValidateChecksums,
16};
17use crate::ledger_id::RefLedgerId;
18use crate::{
19 Client,
20 EntityId,
21 Error,
22 FromProtobuf,
23 ToProtobuf,
24};
25
26#[derive(Hash, PartialEq, Eq, Clone, Copy)]
28pub struct FileId {
29 pub shard: u64,
31
32 pub realm: u64,
34
35 pub num: u64,
37
38 pub checksum: Option<Checksum>,
40}
41
42impl FileId {
43 #[deprecated(note = "use `get_address_book_file_id_for` instead")]
45 pub const ADDRESS_BOOK: Self = Self::new(0, 0, 102);
46
47 #[deprecated(note = "use `get_fee_schedule_file_id_for` instead")]
49 pub const FEE_SCHEDULE: Self = Self::new(0, 0, 111);
50
51 #[deprecated(note = "use `get_exchange_rates_file_id_for` instead")]
53 pub const EXCHANGE_RATES: Self = Self::new(0, 0, 112);
54
55 pub const fn new(shard: u64, realm: u64, num: u64) -> Self {
57 Self { shard, realm, num, checksum: None }
58 }
59
60 pub fn get_address_book_file_id_for(realm: u64, shard: u64) -> Self {
62 let address_book_num = 102;
63 Self::new(shard, realm, address_book_num)
64 }
65
66 pub fn get_fee_schedule_file_id_for(realm: u64, shard: u64) -> Self {
68 let fee_schedule_num = 111;
69 Self::new(shard, realm, fee_schedule_num)
70 }
71
72 pub fn get_exchange_rates_file_id_for(realm: u64, shard: u64) -> Self {
74 let exchange_rates_num = 112;
75 Self::new(shard, realm, exchange_rates_num)
76 }
77
78 pub fn from_bytes(bytes: &[u8]) -> crate::Result<Self> {
84 FromProtobuf::from_bytes(bytes)
85 }
86
87 pub fn from_solidity_address(address: &str) -> crate::Result<Self> {
92 let EntityId { shard, realm, num, checksum } = EntityId::from_solidity_address(address)?;
93
94 Ok(Self { shard, realm, num, checksum })
95 }
96
97 #[must_use]
99 pub fn to_bytes(&self) -> Vec<u8> {
100 ToProtobuf::to_bytes(self)
101 }
102
103 pub fn to_solidity_address(&self) -> crate::Result<String> {
108 EntityId { shard: self.shard, realm: self.realm, num: self.num, checksum: None }
109 .to_solidity_address()
110 }
111
112 #[must_use]
114 pub fn to_string_with_checksum(&self, client: &Client) -> String {
115 EntityId::to_string_with_checksum(self.to_string(), client)
116 }
117
118 pub fn validate_checksum(&self, client: &Client) -> Result<(), Error> {
123 EntityId::validate_checksum(self.shard, self.realm, self.num, self.checksum, client)
124 }
125}
126
127impl ValidateChecksums for FileId {
128 fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
129 EntityId::validate_checksum_for_ledger_id(
130 self.shard,
131 self.realm,
132 self.num,
133 self.checksum,
134 ledger_id,
135 )
136 }
137}
138
139impl Debug for FileId {
140 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
141 write!(f, "\"{self}\"")
142 }
143}
144
145impl Display for FileId {
146 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
147 write!(f, "{}.{}.{}", self.shard, self.realm, self.num)
148 }
149}
150
151impl FromProtobuf<services::FileId> for FileId {
152 fn from_protobuf(pb: services::FileId) -> crate::Result<Self> {
153 Ok(Self {
154 num: pb.file_num as u64,
155 shard: pb.shard_num as u64,
156 realm: pb.realm_num as u64,
157 checksum: None,
158 })
159 }
160}
161
162impl ToProtobuf for FileId {
163 type Protobuf = services::FileId;
164
165 fn to_protobuf(&self) -> Self::Protobuf {
166 services::FileId {
167 file_num: self.num as i64,
168 realm_num: self.realm as i64,
169 shard_num: self.shard as i64,
170 }
171 }
172}
173
174impl From<u64> for FileId {
175 fn from(num: u64) -> Self {
176 Self { num, shard: 0, realm: 0, checksum: None }
177 }
178}
179
180impl FromStr for FileId {
181 type Err = Error;
182
183 fn from_str(s: &str) -> Result<Self, Self::Err> {
184 EntityId::from_str(s).map(Self::from)
185 }
186}
187
188impl From<EntityId> for FileId {
189 fn from(value: EntityId) -> Self {
190 let EntityId { shard, realm, num, checksum } = value;
191 Self { shard, realm, num, checksum }
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use crate::FileId;
198
199 #[test]
200 fn should_serialize_from_string() {
201 assert_eq!("0.0.5005", "0.0.5005".parse::<FileId>().unwrap().to_string());
202 }
203
204 #[test]
205 fn from_bytes() {
206 assert_eq!(
207 "0.0.5005",
208 FileId::from_bytes(&FileId::new(0, 0, 5005).to_bytes()).unwrap().to_string()
209 );
210 }
211
212 #[test]
213 fn from_solidity_address() {
214 assert_eq!(
215 "0.0.5005",
216 FileId::from_solidity_address("000000000000000000000000000000000000138D")
217 .unwrap()
218 .to_string()
219 );
220 }
221
222 #[test]
223 fn to_solidity_address() {
224 assert_eq!(
225 "000000000000000000000000000000000000138d",
226 FileId::new(0, 0, 5005).to_solidity_address().unwrap()
227 );
228 }
229}