hiero_sdk/topic/
topic_id.rs1use 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::{
18 Client,
19 EntityId,
20 Error,
21 FromProtobuf,
22 ToProtobuf,
23};
24
25#[derive(Hash, PartialEq, Eq, Clone, Copy)]
27#[repr(C)]
28pub struct TopicId {
29 pub shard: u64,
31
32 pub realm: u64,
34
35 pub num: u64,
37
38 pub checksum: Option<Checksum>,
40}
41
42impl TopicId {
43 pub const fn new(shard: u64, realm: u64, num: u64) -> Self {
45 Self { shard, realm, num, checksum: None }
46 }
47
48 pub fn from_bytes(bytes: &[u8]) -> crate::Result<Self> {
54 FromProtobuf::from_bytes(bytes)
55 }
56
57 pub fn from_solidity_address(address: &str) -> crate::Result<Self> {
62 let EntityId { shard, realm, num, checksum } = EntityId::from_solidity_address(address)?;
63
64 Ok(Self { shard, realm, num, checksum })
65 }
66
67 #[must_use]
69 pub fn to_bytes(&self) -> Vec<u8> {
70 ToProtobuf::to_bytes(self)
71 }
72
73 pub fn to_solidity_address(&self) -> crate::Result<String> {
78 EntityId { shard: self.shard, realm: self.realm, num: self.num, checksum: None }
79 .to_solidity_address()
80 }
81
82 #[must_use]
84 pub fn to_string_with_checksum(&self, client: &Client) -> String {
85 EntityId::to_string_with_checksum(self.to_string(), client)
86 }
87
88 pub fn validate_checksum(&self, client: &Client) -> crate::Result<()> {
93 EntityId::validate_checksum(self.shard, self.realm, self.num, self.checksum, client)
94 }
95}
96
97impl ValidateChecksums for TopicId {
98 fn validate_checksums(&self, ledger_id: &crate::ledger_id::RefLedgerId) -> Result<(), Error> {
99 EntityId::validate_checksum_for_ledger_id(
100 self.shard,
101 self.realm,
102 self.num,
103 self.checksum,
104 ledger_id,
105 )
106 }
107}
108
109impl Debug for TopicId {
110 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
111 write!(f, "\"{self}\"")
112 }
113}
114
115impl Display for TopicId {
116 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
117 write!(f, "{}.{}.{}", self.shard, self.realm, self.num)
118 }
119}
120
121impl FromProtobuf<services::TopicId> for TopicId {
122 fn from_protobuf(pb: services::TopicId) -> crate::Result<Self> {
123 Ok(Self {
124 num: pb.topic_num as u64,
125 shard: pb.shard_num as u64,
126 realm: pb.realm_num as u64,
127 checksum: None,
128 })
129 }
130}
131
132impl ToProtobuf for TopicId {
133 type Protobuf = services::TopicId;
134
135 fn to_protobuf(&self) -> Self::Protobuf {
136 services::TopicId {
137 topic_num: self.num as i64,
138 realm_num: self.realm as i64,
139 shard_num: self.shard as i64,
140 }
141 }
142}
143
144impl From<u64> for TopicId {
145 fn from(num: u64) -> Self {
146 Self { num, shard: 0, realm: 0, checksum: None }
147 }
148}
149
150impl FromStr for TopicId {
151 type Err = crate::Error;
152
153 fn from_str(s: &str) -> Result<Self, Self::Err> {
154 EntityId::from_str(s).map(Self::from)
155 }
156}
157
158impl From<EntityId> for TopicId {
159 fn from(value: EntityId) -> Self {
160 let EntityId { shard, realm, num, checksum } = value;
161
162 Self { shard, realm, num, checksum }
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use std::str::FromStr;
169
170 use expect_test::expect;
171
172 use crate::TopicId;
173
174 #[test]
175 fn parse() {
176 expect!["0.0.5005"].assert_eq(&TopicId::from_str("0.0.5005").unwrap().to_string());
177 }
178
179 #[test]
180 fn from_bytes() {
181 expect!["0.0.5005"].assert_eq(
182 &TopicId::from_bytes(&TopicId::new(0, 0, 5005).to_bytes()).unwrap().to_string(),
183 );
184 }
185
186 #[test]
187 fn from_solidity_address() {
188 expect!["0.0.5005"].assert_eq(
189 &TopicId::from_solidity_address("000000000000000000000000000000000000138D")
190 .unwrap()
191 .to_string(),
192 );
193 }
194
195 #[test]
196 fn to_solidity_address() {
197 expect!["000000000000000000000000000000000000138d"]
198 .assert_eq(&TopicId::new(0, 0, 5005).to_solidity_address().unwrap());
199 }
200}