1use std::{
6 fmt,
7 fmt::{Debug, Display, Formatter, Write},
8 marker::PhantomData,
9 ops::Deref,
10 str::FromStr,
11};
12
13use fastcrypto::encoding::Hex;
14use iota_protocol_config::ProtocolVersion;
15use move_core_types::{
16 account_address::AccountAddress,
17 language_storage::{StructTag, TypeTag},
18};
19use schemars::JsonSchema;
20use serde::{
21 self, Deserialize, Serialize,
22 de::{Deserializer, Error},
23 ser::{Error as SerError, Serializer},
24};
25use serde_with::{Bytes, DeserializeAs, DisplayFromStr, SerializeAs, serde_as};
26
27use crate::{
28 IOTA_CLOCK_ADDRESS, IOTA_FRAMEWORK_ADDRESS, IOTA_SYSTEM_ADDRESS, IOTA_SYSTEM_STATE_ADDRESS,
29 STARDUST_ADDRESS, parse_iota_struct_tag, parse_iota_type_tag,
30};
31
32#[inline]
33fn to_custom_error<'de, D, E>(e: E) -> D::Error
34where
35 E: Debug,
36 D: Deserializer<'de>,
37{
38 Error::custom(format!("byte deserialization failed, cause by: {:?}", e))
39}
40
41#[inline]
42fn to_custom_ser_error<S, E>(e: E) -> S::Error
43where
44 E: Debug,
45 S: Serializer,
46{
47 S::Error::custom(format!("byte serialization failed, cause by: {:?}", e))
48}
49
50pub struct Readable<H, R> {
66 human_readable: PhantomData<H>,
67 non_human_readable: PhantomData<R>,
68}
69
70impl<T: ?Sized, H, R> SerializeAs<T> for Readable<H, R>
71where
72 H: SerializeAs<T>,
73 R: SerializeAs<T>,
74{
75 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
76 where
77 S: Serializer,
78 {
79 if serializer.is_human_readable() {
80 H::serialize_as(value, serializer)
81 } else {
82 R::serialize_as(value, serializer)
83 }
84 }
85}
86
87impl<'de, R, H, T> DeserializeAs<'de, T> for Readable<H, R>
88where
89 H: DeserializeAs<'de, T>,
90 R: DeserializeAs<'de, T>,
91{
92 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
93 where
94 D: Deserializer<'de>,
95 {
96 if deserializer.is_human_readable() {
97 H::deserialize_as(deserializer)
98 } else {
99 R::deserialize_as(deserializer)
100 }
101 }
102}
103
104pub struct HexAccountAddress;
106
107impl SerializeAs<AccountAddress> for HexAccountAddress {
108 fn serialize_as<S>(value: &AccountAddress, serializer: S) -> Result<S::Ok, S::Error>
109 where
110 S: Serializer,
111 {
112 Hex::serialize_as(value, serializer)
113 }
114}
115
116impl<'de> DeserializeAs<'de, AccountAddress> for HexAccountAddress {
117 fn deserialize_as<D>(deserializer: D) -> Result<AccountAddress, D::Error>
118 where
119 D: Deserializer<'de>,
120 {
121 let s = String::deserialize(deserializer)?;
122 if s.starts_with("0x") {
123 AccountAddress::from_hex_literal(&s)
124 } else {
125 AccountAddress::from_hex(&s)
126 }
127 .map_err(to_custom_error::<'de, D, _>)
128 }
129}
130
131pub struct IotaBitmap;
134
135impl SerializeAs<roaring::RoaringBitmap> for IotaBitmap {
136 fn serialize_as<S>(source: &roaring::RoaringBitmap, serializer: S) -> Result<S::Ok, S::Error>
137 where
138 S: Serializer,
139 {
140 let mut bytes = vec![];
141
142 source
143 .serialize_into(&mut bytes)
144 .map_err(to_custom_ser_error::<S, _>)?;
145 Bytes::serialize_as(&bytes, serializer)
146 }
147}
148
149impl<'de> DeserializeAs<'de, roaring::RoaringBitmap> for IotaBitmap {
150 fn deserialize_as<D>(deserializer: D) -> Result<roaring::RoaringBitmap, D::Error>
151 where
152 D: Deserializer<'de>,
153 {
154 let bytes: Vec<u8> = Bytes::deserialize_as(deserializer)?;
155 roaring::RoaringBitmap::deserialize_from(&bytes[..]).map_err(to_custom_error::<'de, D, _>)
156 }
157}
158
159pub struct IotaStructTag;
160
161impl SerializeAs<StructTag> for IotaStructTag {
162 fn serialize_as<S>(value: &StructTag, serializer: S) -> Result<S::Ok, S::Error>
163 where
164 S: Serializer,
165 {
166 let f = to_iota_struct_tag_string(value).map_err(S::Error::custom)?;
167 f.serialize(serializer)
168 }
169}
170
171const IOTA_ADDRESSES: [AccountAddress; 7] = [
172 AccountAddress::ZERO,
173 AccountAddress::ONE,
174 IOTA_FRAMEWORK_ADDRESS,
175 IOTA_SYSTEM_ADDRESS,
176 STARDUST_ADDRESS,
177 IOTA_SYSTEM_STATE_ADDRESS,
178 IOTA_CLOCK_ADDRESS,
179];
180pub fn to_iota_struct_tag_string(value: &StructTag) -> Result<String, fmt::Error> {
182 let mut f = String::new();
183 let address = if IOTA_ADDRESSES.contains(&value.address) {
185 value.address.short_str_lossless()
186 } else {
187 value.address.to_canonical_string(false)
188 };
189
190 write!(f, "0x{}::{}::{}", address, value.module, value.name)?;
191 if let Some(first_ty) = value.type_params.first() {
192 write!(f, "<")?;
193 write!(f, "{}", to_iota_type_tag_string(first_ty)?)?;
194 for ty in value.type_params.iter().skip(1) {
195 write!(f, ", {}", to_iota_type_tag_string(ty)?)?;
196 }
197 write!(f, ">")?;
198 }
199 Ok(f)
200}
201
202fn to_iota_type_tag_string(value: &TypeTag) -> Result<String, fmt::Error> {
203 match value {
204 TypeTag::Vector(t) => Ok(format!("vector<{}>", to_iota_type_tag_string(t)?)),
205 TypeTag::Struct(s) => to_iota_struct_tag_string(s),
206 _ => Ok(value.to_string()),
207 }
208}
209
210impl<'de> DeserializeAs<'de, StructTag> for IotaStructTag {
211 fn deserialize_as<D>(deserializer: D) -> Result<StructTag, D::Error>
212 where
213 D: Deserializer<'de>,
214 {
215 let s = String::deserialize(deserializer)?;
216 parse_iota_struct_tag(&s).map_err(D::Error::custom)
217 }
218}
219
220pub struct IotaTypeTag;
221
222impl SerializeAs<TypeTag> for IotaTypeTag {
223 fn serialize_as<S>(value: &TypeTag, serializer: S) -> Result<S::Ok, S::Error>
224 where
225 S: Serializer,
226 {
227 let s = to_iota_type_tag_string(value).map_err(S::Error::custom)?;
228 s.serialize(serializer)
229 }
230}
231
232impl<'de> DeserializeAs<'de, TypeTag> for IotaTypeTag {
233 fn deserialize_as<D>(deserializer: D) -> Result<TypeTag, D::Error>
234 where
235 D: Deserializer<'de>,
236 {
237 let s = String::deserialize(deserializer)?;
238 parse_iota_type_tag(&s).map_err(D::Error::custom)
239 }
240}
241
242#[serde_as]
243#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy, JsonSchema)]
244pub struct BigInt<T>(
245 #[schemars(with = "String")]
246 #[serde_as(as = "DisplayFromStr")]
247 T,
248)
249where
250 T: Display + FromStr,
251 <T as FromStr>::Err: Display;
252
253impl<T> BigInt<T>
254where
255 T: Display + FromStr,
256 <T as FromStr>::Err: Display,
257{
258 pub fn into_inner(self) -> T {
259 self.0
260 }
261}
262
263impl<T> SerializeAs<T> for BigInt<T>
264where
265 T: Display + FromStr + Copy,
266 <T as FromStr>::Err: Display,
267{
268 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
269 where
270 S: Serializer,
271 {
272 BigInt(*value).serialize(serializer)
273 }
274}
275
276impl<'de, T> DeserializeAs<'de, T> for BigInt<T>
277where
278 T: Display + FromStr + Copy,
279 <T as FromStr>::Err: Display,
280{
281 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
282 where
283 D: Deserializer<'de>,
284 {
285 Ok(*BigInt::deserialize(deserializer)?)
286 }
287}
288
289impl<T> From<T> for BigInt<T>
290where
291 T: Display + FromStr,
292 <T as FromStr>::Err: Display,
293{
294 fn from(v: T) -> BigInt<T> {
295 BigInt(v)
296 }
297}
298
299impl<T> Deref for BigInt<T>
300where
301 T: Display + FromStr,
302 <T as FromStr>::Err: Display,
303{
304 type Target = T;
305
306 fn deref(&self) -> &Self::Target {
307 &self.0
308 }
309}
310
311impl<T> Display for BigInt<T>
312where
313 T: Display + FromStr,
314 <T as FromStr>::Err: Display,
315{
316 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
317 write!(f, "{}", self.0)
318 }
319}
320
321#[serde_as]
322#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy, JsonSchema)]
323pub struct SequenceNumber(#[schemars(with = "BigInt<u64>")] u64);
324
325impl SerializeAs<crate::base_types::SequenceNumber> for SequenceNumber {
326 fn serialize_as<S>(
327 value: &crate::base_types::SequenceNumber,
328 serializer: S,
329 ) -> Result<S::Ok, S::Error>
330 where
331 S: Serializer,
332 {
333 let s = value.value().to_string();
334 s.serialize(serializer)
335 }
336}
337
338impl<'de> DeserializeAs<'de, crate::base_types::SequenceNumber> for SequenceNumber {
339 fn deserialize_as<D>(deserializer: D) -> Result<crate::base_types::SequenceNumber, D::Error>
340 where
341 D: Deserializer<'de>,
342 {
343 let b = BigInt::deserialize(deserializer)?;
344 Ok(crate::base_types::SequenceNumber::from_u64(*b))
345 }
346}
347
348#[serde_as]
349#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy, JsonSchema)]
350#[serde(rename = "ProtocolVersion")]
351pub struct AsProtocolVersion(#[schemars(with = "BigInt<u64>")] u64);
352
353impl SerializeAs<ProtocolVersion> for AsProtocolVersion {
354 fn serialize_as<S>(value: &ProtocolVersion, serializer: S) -> Result<S::Ok, S::Error>
355 where
356 S: Serializer,
357 {
358 let s = value.as_u64().to_string();
359 s.serialize(serializer)
360 }
361}
362
363impl<'de> DeserializeAs<'de, ProtocolVersion> for AsProtocolVersion {
364 fn deserialize_as<D>(deserializer: D) -> Result<ProtocolVersion, D::Error>
365 where
366 D: Deserializer<'de>,
367 {
368 let b = BigInt::<u64>::deserialize(deserializer)?;
369 Ok(ProtocolVersion::from(*b))
370 }
371}