polymesh_api_client/
type_def.rs

1#![allow(deprecated)]
2
3use core::fmt;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8use codec::{Decode, Encode};
9
10#[cfg(not(feature = "std"))]
11use alloc::{format, string::String};
12use sp_std::prelude::*;
13
14pub use scale_info::{form::PortableForm, TypeDefPrimitive};
15
16#[derive(Clone, Debug, Default)]
17pub struct TypeForm;
18
19impl scale_info::form::Form for TypeForm {
20  type Type = TypeId;
21  type String = String;
22}
23
24#[derive(Clone, Debug, Default, Decode, Encode)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub struct Path {
27  pub segments: Vec<String>,
28}
29
30impl fmt::Display for Path {
31  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32    write!(f, "{}", self.segments.join("::"))
33  }
34}
35
36impl Path {
37  pub fn new(ident: &str, module_path: &str) -> Self {
38    let mut segments = module_path
39      .split("::")
40      .filter(|s| !s.is_empty())
41      .map(|s| s.into())
42      .collect::<Vec<_>>();
43    if ident != "" {
44      segments.push(ident.into());
45    }
46    Self { segments }
47  }
48
49  pub fn is_empty(&self) -> bool {
50    self.segments.is_empty()
51  }
52
53  pub fn ident(&self) -> Option<&str> {
54    self.segments.last().map(|s| s.as_str())
55  }
56
57  pub fn namespace(&self) -> &[String] {
58    self.segments.split_last().map(|(_, ns)| ns).unwrap_or(&[])
59  }
60}
61
62#[derive(Clone, Debug, Decode, Encode)]
63#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
64pub struct TypeParameter {
65  pub name: String,
66  #[cfg_attr(feature = "serde", serde(rename = "type"))]
67  pub ty: Option<TypeId>,
68}
69
70#[derive(Clone, Debug, Decode, Encode)]
71#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
72pub struct Type {
73  #[cfg_attr(
74    feature = "serde",
75    serde(skip_serializing_if = "Path::is_empty", default)
76  )]
77  pub path: Path,
78  #[cfg_attr(
79    feature = "serde",
80    serde(skip_serializing_if = "Vec::is_empty", default)
81  )]
82  pub type_params: Vec<TypeParameter>,
83  #[cfg_attr(feature = "serde", serde(rename = "def"))]
84  pub type_def: TypeDef,
85  #[cfg_attr(
86    feature = "serde",
87    serde(skip_serializing_if = "Vec::is_empty", default)
88  )]
89  pub docs: Vec<String>,
90}
91
92impl Type {
93  pub fn new(name: &str, type_def: TypeDef) -> Self {
94    Self {
95      path: Path::new(name, ""),
96      type_def,
97      type_params: Default::default(),
98      docs: Default::default(),
99    }
100  }
101
102  pub fn path(&self) -> &Path {
103    &self.path
104  }
105
106  pub fn type_params(&self) -> &[TypeParameter] {
107    self.type_params.as_slice()
108  }
109
110  pub fn type_def(&self) -> &TypeDef {
111    &self.type_def
112  }
113
114  pub fn is_u8(&self) -> bool {
115    match &self.type_def {
116      TypeDef::Primitive(TypeDefPrimitive::U8) => true,
117      _ => false,
118    }
119  }
120}
121
122#[derive(Clone, Debug, Decode, Encode)]
123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
124pub struct Field {
125  #[cfg_attr(
126    feature = "serde",
127    serde(skip_serializing_if = "Option::is_none", default)
128  )]
129  pub name: Option<String>,
130  #[cfg_attr(feature = "serde", serde(rename = "type"))]
131  pub ty: TypeId,
132  #[cfg_attr(
133    feature = "serde",
134    serde(skip_serializing_if = "Option::is_none", default)
135  )]
136  pub type_name: Option<String>,
137  #[cfg_attr(
138    feature = "serde",
139    serde(skip_serializing_if = "Vec::is_empty", default)
140  )]
141  pub docs: Vec<String>,
142}
143
144impl Field {
145  pub fn new(ty: TypeId) -> Self {
146    Self {
147      name: None,
148      ty,
149      type_name: None,
150      docs: Vec::new(),
151    }
152  }
153
154  pub fn new_named(name: &str, ty: TypeId, type_name: Option<String>) -> Self {
155    Self {
156      name: Some(name.into()),
157      ty,
158      type_name,
159      docs: Vec::new(),
160    }
161  }
162}
163
164#[derive(Clone, Debug, Default, Decode, Encode)]
165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
166pub struct Variant {
167  pub name: String,
168  #[cfg_attr(
169    feature = "serde",
170    serde(skip_serializing_if = "Vec::is_empty", default)
171  )]
172  pub fields: Vec<Field>,
173  pub index: u8,
174  #[cfg_attr(
175    feature = "serde",
176    serde(skip_serializing_if = "Vec::is_empty", default)
177  )]
178  pub docs: Vec<String>,
179}
180
181impl Variant {
182  pub fn new(name: &str, fields: Vec<Field>, index: u8) -> Self {
183    Self {
184      name: name.into(),
185      fields,
186      index,
187      docs: Vec::new(),
188    }
189  }
190
191  /// Check if the variant is a tuple enum variant or struct enum variant (all fields need to have names).
192  pub fn is_struct(&self) -> bool {
193    named_fields(self.fields.as_slice())
194  }
195}
196
197#[derive(Clone, Debug, Default, Decode, Encode)]
198#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
199pub struct TypeDefVariant {
200  #[cfg_attr(
201    feature = "serde",
202    serde(skip_serializing_if = "Vec::is_empty", default)
203  )]
204  pub variants: Vec<Variant>,
205}
206
207impl TypeDefVariant {
208  pub fn new() -> Self {
209    Self::default()
210  }
211
212  pub fn new_variants(variants: Vec<Variant>) -> Self {
213    Self { variants }
214  }
215
216  pub fn new_option(ty: TypeId) -> Self {
217    Self {
218      variants: vec![
219        Variant::new("None", vec![], 0),
220        Variant::new("Some", vec![Field::new(ty)], 1),
221      ],
222    }
223  }
224
225  pub fn new_result(ok_ty: TypeId, err_ty: TypeId) -> Self {
226    Self {
227      variants: vec![
228        Variant::new("Ok", vec![Field::new(ok_ty)], 0),
229        Variant::new("Err", vec![Field::new(err_ty)], 1),
230      ],
231    }
232  }
233
234  pub fn insert(&mut self, index: u8, name: &str, field: Option<TypeId>) {
235    self.variants.push(Variant {
236      name: name.into(),
237      index,
238      fields: field.into_iter().map(|id| Field::new(id)).collect(),
239      docs: vec![],
240    })
241  }
242
243  pub fn get_by_idx(&self, index: u8) -> Option<&Variant> {
244    // Try quick search.
245    let variant = self
246      .variants
247      .get(index as usize)
248      .filter(|v| v.index == index);
249    if variant.is_some() {
250      return variant;
251    }
252    // fallback to linear search.
253    for variant in &self.variants {
254      if variant.index == index {
255        return Some(variant);
256      }
257    }
258    // Not found.
259    None
260  }
261
262  pub fn get_by_name(&self, name: &str) -> Option<&Variant> {
263    self.variants.iter().find(|v| v.name == name)
264  }
265}
266
267/// Check if the variant is a tuple enum variant or struct enum variant (all fields need to have names).
268fn named_fields(fields: &[Field]) -> bool {
269  let mut named = true;
270  for field in fields {
271    if field.name.is_none() {
272      // If there are any unnamed fields, then it is a tuple.
273      named = false;
274      break;
275    }
276  }
277  named
278}
279
280#[derive(Clone, Debug, Default, Decode, Encode)]
281#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
282pub struct TypeDefComposite {
283  #[cfg_attr(
284    feature = "serde",
285    serde(skip_serializing_if = "Vec::is_empty", default)
286  )]
287  pub fields: Vec<Field>,
288}
289
290impl TypeDefComposite {
291  pub fn new(fields: Vec<Field>) -> Self {
292    Self { fields }
293  }
294
295  /// Check if the composite is a tuple variant or struct variant (all fields need to have names).
296  pub fn is_struct(&self) -> bool {
297    named_fields(self.fields.as_slice())
298  }
299}
300
301#[derive(Clone, Debug, Default, Decode, Encode)]
302#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
303#[cfg_attr(feature = "serde", serde(transparent))]
304pub struct TypeDefTuple {
305  pub fields: Vec<TypeId>,
306}
307
308impl TypeDefTuple {
309  pub fn new(fields: Vec<TypeId>) -> Self {
310    Self { fields }
311  }
312
313  pub fn new_type(field: TypeId) -> Self {
314    Self {
315      fields: vec![field],
316    }
317  }
318
319  pub fn unit() -> Self {
320    Self::new(vec![])
321  }
322
323  pub fn is_unit(&self) -> bool {
324    self.fields.is_empty()
325  }
326
327  pub fn fields(&self) -> &[TypeId] {
328    self.fields.as_slice()
329  }
330}
331
332#[derive(Clone, Debug, Decode, Encode)]
333#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
334pub struct TypeDefSequence {
335  #[cfg_attr(feature = "serde", serde(rename = "type"))]
336  pub type_param: TypeId,
337}
338
339impl TypeDefSequence {
340  pub fn new(type_param: TypeId) -> Self {
341    Self { type_param }
342  }
343
344  pub fn type_param(&self) -> TypeId {
345    self.type_param
346  }
347}
348
349#[derive(Clone, Debug, Decode, Encode)]
350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
351pub struct TypeDefArray {
352  pub len: u32,
353  #[cfg_attr(feature = "serde", serde(rename = "type"))]
354  pub type_param: TypeId,
355}
356
357impl TypeDefArray {
358  pub fn new(len: u32, type_param: TypeId) -> Self {
359    Self { len, type_param }
360  }
361
362  pub fn type_param(&self) -> TypeId {
363    self.type_param
364  }
365
366  pub fn len(&self) -> u32 {
367    self.len
368  }
369}
370
371#[derive(Clone, Debug, Decode, Encode)]
372#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
373pub struct TypeDefCompact {
374  #[cfg_attr(feature = "serde", serde(rename = "type"))]
375  pub type_param: TypeId,
376}
377
378impl TypeDefCompact {
379  pub fn new(type_param: TypeId) -> Self {
380    Self { type_param }
381  }
382
383  pub fn type_param(&self) -> TypeId {
384    self.type_param
385  }
386}
387
388#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Decode, Encode)]
389#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
390pub struct TypeId(#[codec(compact)] pub u32);
391
392impl TypeId {
393  pub fn id(&self) -> u32 {
394    self.0
395  }
396
397  pub fn inc(&mut self) {
398    self.0 += 1;
399  }
400}
401
402impl From<u32> for TypeId {
403  fn from(id: u32) -> Self {
404    Self(id)
405  }
406}
407
408impl From<usize> for TypeId {
409  fn from(id: usize) -> Self {
410    Self(id as u32)
411  }
412}
413
414impl From<TypeId> for usize {
415  fn from(id: TypeId) -> Self {
416    id.0 as Self
417  }
418}
419
420impl core::ops::Deref for TypeId {
421  type Target = u32;
422
423  fn deref(&self) -> &Self::Target {
424    &self.0
425  }
426}
427
428#[derive(Clone, Debug, Decode, Encode)]
429#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
430#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
431pub enum TypeDef {
432  #[codec(index = 0)]
433  Composite(TypeDefComposite),
434  #[codec(index = 1)]
435  Variant(TypeDefVariant),
436  #[codec(index = 2)]
437  Sequence(TypeDefSequence),
438  #[codec(index = 3)]
439  Array(TypeDefArray),
440  #[codec(index = 4)]
441  Tuple(TypeDefTuple),
442  #[codec(index = 5)]
443  Primitive(TypeDefPrimitive),
444  #[codec(index = 6)]
445  Compact(TypeDefCompact),
446  // TODO: BitSequence
447}
448
449impl TypeDef {
450  pub fn to_string(&mut self) -> String {
451    format!("TypeDef: {:?}", self)
452  }
453
454  pub fn new_type(ty: TypeId) -> Self {
455    Self::Tuple(TypeDefTuple::new_type(ty))
456  }
457
458  pub fn new_tuple(fields: Vec<TypeId>) -> Self {
459    Self::Tuple(TypeDefTuple::new(fields))
460  }
461}
462
463impl From<TypeDefComposite> for TypeDef {
464  fn from(def: TypeDefComposite) -> Self {
465    Self::Composite(def)
466  }
467}
468
469impl From<TypeDefVariant> for TypeDef {
470  fn from(def: TypeDefVariant) -> Self {
471    Self::Variant(def)
472  }
473}
474
475impl From<TypeDefSequence> for TypeDef {
476  fn from(def: TypeDefSequence) -> Self {
477    Self::Sequence(def)
478  }
479}
480
481impl From<TypeDefArray> for TypeDef {
482  fn from(def: TypeDefArray) -> Self {
483    Self::Array(def)
484  }
485}
486
487impl From<TypeDefTuple> for TypeDef {
488  fn from(def: TypeDefTuple) -> Self {
489    Self::Tuple(def)
490  }
491}
492
493impl From<TypeDefPrimitive> for TypeDef {
494  fn from(def: TypeDefPrimitive) -> Self {
495    Self::Primitive(def)
496  }
497}
498
499impl From<TypeDefCompact> for TypeDef {
500  fn from(def: TypeDefCompact) -> Self {
501    Self::Compact(def)
502  }
503}
504
505#[derive(Clone, Debug, Decode, Encode)]
506#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
507pub struct PortableType {
508  pub id: TypeId,
509  #[cfg_attr(feature = "serde", serde(rename = "type"))]
510  pub ty: Type,
511}
512
513impl PortableType {
514  pub fn id(&self) -> TypeId {
515    self.id
516  }
517
518  pub fn ty(&self) -> &Type {
519    &self.ty
520  }
521}
522
523#[derive(Clone, Debug, Decode, Encode)]
524#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
525pub struct PortableRegistry {
526  pub types: Vec<PortableType>,
527}
528
529impl PortableRegistry {
530  pub fn resolve<T: Into<TypeId>>(&self, id: T) -> Option<&Type> {
531    let id = id.into();
532    self.types.get(id.0 as usize).map(|t| t.ty())
533  }
534
535  pub fn types(&self) -> &[PortableType] {
536    self.types.as_slice()
537  }
538}
539
540impl From<&scale_info::PortableRegistry> for PortableRegistry {
541  fn from(other: &scale_info::PortableRegistry) -> Self {
542    Self {
543      types: other
544        .types()
545        .iter()
546        .map(|t| PortableType {
547          id: t.id().into(),
548          ty: t.ty().into(),
549        })
550        .collect(),
551    }
552  }
553}
554
555impl From<&scale_info::TypeParameter<PortableForm>> for TypeParameter {
556  fn from(other: &scale_info::TypeParameter<PortableForm>) -> Self {
557    Self {
558      name: other.name().clone(),
559      ty: other.ty().map(|t| t.id().into()),
560    }
561  }
562}
563
564impl From<&scale_info::Type<PortableForm>> for Type {
565  fn from(other: &scale_info::Type<PortableForm>) -> Self {
566    Self {
567      path: other.path().into(),
568      type_params: other.type_params().iter().map(|p| p.into()).collect(),
569      type_def: other.type_def().into(),
570      docs: other.docs().into(),
571    }
572  }
573}
574
575impl From<&scale_info::Path<PortableForm>> for Path {
576  fn from(other: &scale_info::Path<PortableForm>) -> Self {
577    Self {
578      segments: other.segments().iter().cloned().collect(),
579    }
580  }
581}
582
583impl From<&scale_info::Field<PortableForm>> for Field {
584  fn from(other: &scale_info::Field<PortableForm>) -> Self {
585    Self {
586      name: other.name().cloned().into(),
587      ty: other.ty().id().into(),
588      type_name: other.type_name().cloned().into(),
589      docs: other.docs().into(),
590    }
591  }
592}
593
594impl From<&scale_info::Variant<PortableForm>> for Variant {
595  fn from(other: &scale_info::Variant<PortableForm>) -> Self {
596    Self {
597      name: other.name().into(),
598      fields: other.fields().iter().map(|f| f.into()).collect(),
599      index: other.index().into(),
600      docs: other.docs().into(),
601    }
602  }
603}
604
605impl From<&scale_info::TypeDefComposite<PortableForm>> for TypeDefComposite {
606  fn from(other: &scale_info::TypeDefComposite<PortableForm>) -> Self {
607    Self {
608      fields: other.fields().iter().map(|v| v.into()).collect(),
609    }
610  }
611}
612
613impl From<&scale_info::TypeDefVariant<PortableForm>> for TypeDefVariant {
614  fn from(other: &scale_info::TypeDefVariant<PortableForm>) -> Self {
615    Self {
616      variants: other.variants().iter().map(|v| v.into()).collect(),
617    }
618  }
619}
620
621impl From<&scale_info::TypeDefSequence<PortableForm>> for TypeDefSequence {
622  fn from(other: &scale_info::TypeDefSequence<PortableForm>) -> Self {
623    Self {
624      type_param: other.type_param().id().into(),
625    }
626  }
627}
628
629impl From<&scale_info::TypeDefArray<PortableForm>> for TypeDefArray {
630  fn from(other: &scale_info::TypeDefArray<PortableForm>) -> Self {
631    Self {
632      len: other.len(),
633      type_param: other.type_param().id().into(),
634    }
635  }
636}
637
638impl From<&scale_info::TypeDefTuple<PortableForm>> for TypeDefTuple {
639  fn from(other: &scale_info::TypeDefTuple<PortableForm>) -> Self {
640    Self {
641      fields: other.fields().iter().map(|v| v.id().into()).collect(),
642    }
643  }
644}
645
646impl From<&scale_info::TypeDefCompact<PortableForm>> for TypeDefCompact {
647  fn from(other: &scale_info::TypeDefCompact<PortableForm>) -> Self {
648    Self {
649      type_param: other.type_param().id().into(),
650    }
651  }
652}
653
654impl From<&scale_info::TypeDef<PortableForm>> for TypeDef {
655  fn from(other: &scale_info::TypeDef<PortableForm>) -> Self {
656    match other {
657      scale_info::TypeDef::Composite(c) => TypeDef::Composite(c.into()),
658      scale_info::TypeDef::Variant(v) => TypeDef::Variant(v.into()),
659      scale_info::TypeDef::Sequence(s) => TypeDef::Sequence(s.into()),
660      scale_info::TypeDef::Array(a) => TypeDef::Array(a.into()),
661      scale_info::TypeDef::Tuple(t) => TypeDef::Tuple(t.into()),
662      scale_info::TypeDef::Primitive(p) => TypeDef::Primitive(p.clone()),
663      scale_info::TypeDef::Compact(ty) => TypeDef::Compact(ty.into()),
664      _ => {
665        todo!();
666      }
667    }
668  }
669}