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