polymesh_api_client/
serde_impl.rs

1use serde::{de, ser, Deserialize, Serialize};
2
3use alloc::format;
4use core::{fmt, str::FromStr};
5use sp_core::crypto::Ss58Codec;
6
7use crate::basic_types::{AccountId, AccountTraits, AssetId, IdentityId, MultiAddress};
8
9impl<AccountId, AccountIndex> ser::Serialize for MultiAddress<AccountId, AccountIndex>
10where
11  AccountId: AccountTraits,
12  AccountIndex: AccountTraits,
13{
14  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
15  where
16    S: ser::Serializer,
17  {
18    match self {
19      Self::Id(account) => {
20        if serializer.is_human_readable() {
21          account.serialize(serializer)
22        } else {
23          serializer.serialize_newtype_variant("MultiAddress", 0, "Id", account)
24        }
25      }
26      Self::Index(index) => serializer.serialize_newtype_variant("MultiAddress", 1, "Index", index),
27      Self::Raw(data) => {
28        if serializer.is_human_readable() {
29          let h = hex::encode(data.as_slice());
30          serializer.serialize_newtype_variant("MultiAddress", 2, "Raw", &h)
31        } else {
32          serializer.serialize_newtype_variant("MultiAddress", 2, "Raw", data)
33        }
34      }
35      Self::Address32(address) => {
36        if serializer.is_human_readable() {
37          let h = hex::encode(&address[..]);
38          serializer.serialize_newtype_variant("MultiAddress", 3, "Address32", &h)
39        } else {
40          serializer.serialize_newtype_variant("MultiAddress", 3, "Address32", address)
41        }
42      }
43      Self::Address20(address) => {
44        if serializer.is_human_readable() {
45          let h = hex::encode(&address[..]);
46          serializer.serialize_newtype_variant("MultiAddress", 4, "Address20", &h)
47        } else {
48          serializer.serialize_newtype_variant("MultiAddress", 4, "Address20", address)
49        }
50      }
51    }
52  }
53}
54
55#[derive(Deserialize)]
56#[serde(field_identifier, rename_all = "PascalCase")]
57enum MultiAddressField {
58  Id,
59  Index,
60  Raw,
61  Address32,
62  Address20,
63}
64
65#[derive(Default)]
66struct MultiAddressVisitor<AccountId: AccountTraits, AccountIndex: AccountTraits> {
67  is_human_readable: bool,
68  _phantom: core::marker::PhantomData<(AccountId, AccountIndex)>,
69}
70
71impl<AccountId: AccountTraits, AccountIndex: AccountTraits>
72  MultiAddressVisitor<AccountId, AccountIndex>
73{
74  fn new(is_human_readable: bool) -> Self {
75    Self {
76      is_human_readable,
77      _phantom: Default::default(),
78    }
79  }
80}
81
82impl<'de, AccountId, AccountIndex> de::Visitor<'de> for MultiAddressVisitor<AccountId, AccountIndex>
83where
84  AccountId: AccountTraits,
85  AccountIndex: AccountTraits,
86{
87  type Value = MultiAddress<AccountId, AccountIndex>;
88
89  fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
90    formatter.write_str("AccountId or MultiAddress")
91  }
92
93  fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
94  where
95    E: de::Error,
96  {
97    let account = AccountId::from_str(v)
98      .map_err(|_e| de::Error::custom(format!("Failed to decode AccountId")))?;
99    Ok(MultiAddress::Id(account))
100  }
101
102  fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
103  where
104    V: de::MapAccess<'de>,
105  {
106    let mut address = None;
107    while let Some(key) = map.next_key()? {
108      match key {
109        MultiAddressField::Id => {
110          if address.is_some() {
111            return Err(de::Error::duplicate_field("Id"));
112          }
113          address = Some(MultiAddress::Id(map.next_value()?));
114        }
115        MultiAddressField::Index => {
116          if address.is_some() {
117            return Err(de::Error::duplicate_field("Index"));
118          }
119          address = Some(MultiAddress::Index(map.next_value()?));
120        }
121        MultiAddressField::Raw => {
122          if address.is_some() {
123            return Err(de::Error::duplicate_field("Raw"));
124          }
125          if self.is_human_readable {
126            let h: &str = map.next_value()?;
127            let off = if h.starts_with("0x") { 2 } else { 0 };
128            let data = hex::decode(&h[off..]).map_err(|e| de::Error::custom(e))?;
129            address = Some(MultiAddress::Raw(data));
130          } else {
131            address = Some(MultiAddress::Raw(map.next_value()?));
132          }
133        }
134        MultiAddressField::Address32 => {
135          if address.is_some() {
136            return Err(de::Error::duplicate_field("Address32"));
137          }
138          if self.is_human_readable {
139            let h: &str = map.next_value()?;
140            let mut data = [0u8; 32];
141            let off = if h.starts_with("0x") { 2 } else { 0 };
142            hex::decode_to_slice(&h[off..], &mut data).map_err(|e| de::Error::custom(e))?;
143            address = Some(MultiAddress::Address32(data));
144          } else {
145            address = Some(MultiAddress::Address32(map.next_value()?));
146          }
147        }
148        MultiAddressField::Address20 => {
149          if address.is_some() {
150            return Err(de::Error::duplicate_field("Address20"));
151          }
152          if self.is_human_readable {
153            let h: &str = map.next_value()?;
154            let mut data = [0u8; 20];
155            let off = if h.starts_with("0x") { 2 } else { 0 };
156            hex::decode_to_slice(&h[off..], &mut data).map_err(|e| de::Error::custom(e))?;
157            address = Some(MultiAddress::Address20(data));
158          } else {
159            address = Some(MultiAddress::Address20(map.next_value()?));
160          }
161        }
162      }
163    }
164    let address =
165      address.ok_or_else(|| de::Error::missing_field("Id, Index, Raw, Address32, or Address20"))?;
166    Ok(address)
167  }
168}
169
170impl<'de, AccountId, AccountIndex> Deserialize<'de> for MultiAddress<AccountId, AccountIndex>
171where
172  AccountId: AccountTraits,
173  AccountIndex: AccountTraits,
174{
175  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
176  where
177    D: de::Deserializer<'de>,
178  {
179    let visitor = MultiAddressVisitor::new(deserializer.is_human_readable());
180    if deserializer.is_human_readable() {
181      deserializer.deserialize_any(visitor)
182    } else {
183      deserializer.deserialize_enum(
184        "MultiAddress",
185        &["Id", "Index", "Raw", "Address32", "Address20"],
186        visitor,
187      )
188    }
189  }
190}
191
192impl Serialize for AccountId {
193  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
194  where
195    S: ser::Serializer,
196  {
197    if serializer.is_human_readable() {
198      let ss58 = self.to_ss58check();
199      serializer.serialize_str(&ss58)
200    } else {
201      self.0.serialize(serializer)
202    }
203  }
204}
205
206impl<'de> Deserialize<'de> for AccountId {
207  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
208  where
209    D: de::Deserializer<'de>,
210  {
211    if deserializer.is_human_readable() {
212      struct StringOrBytesVisitor;
213
214      impl<'de> de::Visitor<'de> for StringOrBytesVisitor {
215        type Value = AccountId;
216
217        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
218          formatter.write_str("a hex string or [u8; 32]")
219        }
220
221        fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
222        where
223          E: de::Error,
224        {
225          Ok(AccountId::from_str(s).map_err(|e| de::Error::custom(e))?)
226        }
227
228        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
229        where
230          A: de::SeqAccess<'de>,
231        {
232          let mut id = AccountId::default();
233          for n in 0..32 {
234            id.0[n] = seq
235              .next_element()?
236              .ok_or_else(|| de::Error::invalid_length(n, &self))?;
237          }
238          Ok(id)
239        }
240      }
241      deserializer.deserialize_any(StringOrBytesVisitor)
242    } else {
243      Ok(Self(Deserialize::deserialize(deserializer)?))
244    }
245  }
246}
247
248impl Serialize for IdentityId {
249  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
250  where
251    S: ser::Serializer,
252  {
253    if serializer.is_human_readable() {
254      let h = format!("0x{}", hex::encode(&self.0));
255      serializer.serialize_str(&h)
256    } else {
257      self.0.serialize(serializer)
258    }
259  }
260}
261
262impl<'de> Deserialize<'de> for IdentityId {
263  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
264  where
265    D: de::Deserializer<'de>,
266  {
267    if deserializer.is_human_readable() {
268      struct StringOrBytesVisitor;
269
270      impl<'de> de::Visitor<'de> for StringOrBytesVisitor {
271        type Value = IdentityId;
272
273        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
274          formatter.write_str("a hex string or [u8; 32]")
275        }
276
277        fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
278        where
279          E: de::Error,
280        {
281          let mut id = IdentityId::default();
282          let off = if s.starts_with("0x") { 2 } else { 0 };
283          hex::decode_to_slice(&s[off..], &mut id.0).map_err(|e| de::Error::custom(e))?;
284          Ok(id)
285        }
286
287        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
288        where
289          A: de::SeqAccess<'de>,
290        {
291          let mut id = IdentityId::default();
292          for n in 0..32 {
293            id.0[n] = seq
294              .next_element()?
295              .ok_or_else(|| de::Error::invalid_length(n, &self))?;
296          }
297          Ok(id)
298        }
299      }
300      deserializer.deserialize_any(StringOrBytesVisitor)
301    } else {
302      Ok(Self(Deserialize::deserialize(deserializer)?))
303    }
304  }
305}
306
307impl Serialize for AssetId {
308  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
309  where
310    S: ser::Serializer,
311  {
312    self.as_uuid().serialize(serializer)
313  }
314}
315
316impl<'de> Deserialize<'de> for AssetId {
317  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
318  where
319    D: de::Deserializer<'de>,
320  {
321    let uuid: uuid::Uuid = Deserialize::deserialize(deserializer)?;
322    Ok(Self(uuid.into_bytes()))
323  }
324}