scale_info/ty/
mod.rs

1// Copyright 2019-2022 Parity Technologies (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::prelude::{vec, vec::Vec};
16
17use crate::{
18    build::TypeBuilder,
19    form::{Form, MetaForm, PortableForm},
20    IntoPortable, MetaType, Registry, TypeInfo,
21};
22use derive_more::From;
23use scale::Encode;
24#[cfg(feature = "serde")]
25use serde::{de::DeserializeOwned, Deserialize, Serialize};
26
27mod composite;
28mod fields;
29mod path;
30mod variant;
31
32pub use self::{composite::*, fields::*, path::*, variant::*};
33
34/// A [`Type`] definition with optional metadata.
35#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36#[cfg_attr(
37    feature = "serde",
38    serde(bound(
39        serialize = "T::Type: Serialize, T::String: Serialize",
40        deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
41    ))
42)]
43#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
44#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
45#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
46#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode)]
47pub struct Type<T: Form = MetaForm> {
48    /// The unique path to the type. Can be empty for built-in types
49    #[cfg_attr(
50        feature = "serde",
51        serde(skip_serializing_if = "Path::is_empty", default)
52    )]
53    pub path: Path<T>,
54    /// The generic type parameters of the type in use. Empty for non generic types
55    #[cfg_attr(
56        feature = "serde",
57        serde(rename = "params", skip_serializing_if = "Vec::is_empty", default)
58    )]
59    pub type_params: Vec<TypeParameter<T>>,
60    /// The actual type definition
61    #[cfg_attr(feature = "serde", serde(rename = "def"))]
62    pub type_def: TypeDef<T>,
63    /// Documentation
64    #[cfg_attr(
65        feature = "serde",
66        serde(skip_serializing_if = "Vec::is_empty", default)
67    )]
68    pub docs: Vec<T::String>,
69}
70
71impl IntoPortable for Type {
72    type Output = Type<PortableForm>;
73
74    fn into_portable(self, registry: &mut Registry) -> Self::Output {
75        Type {
76            path: self.path.into_portable(registry),
77            type_params: registry.map_into_portable(self.type_params),
78            type_def: self.type_def.into_portable(registry),
79            docs: self.docs.into_iter().map(Into::into).collect(),
80        }
81    }
82}
83
84macro_rules! impl_from_type_def_for_type {
85    ( $( $t:ty  ), + $(,)?) => { $(
86        impl<F: Form> From<$t> for Type<F> {
87            fn from(item: $t) -> Self {
88                Self::new(Path::voldemort(), Vec::new(), item, Vec::new())
89            }
90        }
91    )* }
92}
93
94impl_from_type_def_for_type!(
95    TypeDefPrimitive,
96    TypeDefArray<F>,
97    TypeDefSequence<F>,
98    TypeDefTuple<F>,
99    TypeDefCompact<F>,
100    TypeDefBitSequence<F>,
101);
102
103impl Type {
104    /// Create a [`TypeBuilder`](`crate::build::TypeBuilder`) the public API for constructing a
105    /// [`Type`] of [`MetaForm`].
106    pub fn builder() -> TypeBuilder {
107        TypeBuilder::default()
108    }
109
110    /// Create a [`TypeBuilder`](`crate::build::TypeBuilder`) the public API for constructing a
111    /// [`Type`] of [`PortableForm`] for use at runtime.
112    pub fn builder_portable() -> TypeBuilder<PortableForm> {
113        TypeBuilder::default()
114    }
115}
116
117impl<F> Type<F>
118where
119    F: Form,
120{
121    /// Create a [`Type`].
122    pub fn new<I, D>(path: Path<F>, type_params: I, type_def: D, docs: Vec<F::String>) -> Type<F>
123    where
124        I: IntoIterator<Item = TypeParameter<F>>,
125        D: Into<TypeDef<F>>,
126    {
127        Self {
128            path,
129            type_params: type_params.into_iter().collect(),
130            type_def: type_def.into(),
131            docs,
132        }
133    }
134}
135
136impl<T> Type<T>
137where
138    T: Form,
139{
140    /// Returns the path of the type
141    #[deprecated(
142        since = "2.5.0",
143        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
144    )]
145    pub fn path(&self) -> &Path<T> {
146        &self.path
147    }
148
149    /// Returns the generic type parameters of the type
150    #[deprecated(
151        since = "2.5.0",
152        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
153    )]
154    pub fn type_params(&self) -> &[TypeParameter<T>] {
155        &self.type_params
156    }
157
158    /// Returns the definition of the type
159    #[deprecated(
160        since = "2.5.0",
161        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
162    )]
163    pub fn type_def(&self) -> &TypeDef<T> {
164        &self.type_def
165    }
166
167    /// Returns the documentation of the type
168    #[deprecated(
169        since = "2.5.0",
170        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
171    )]
172    pub fn docs(&self) -> &[T::String] {
173        &self.docs
174    }
175}
176
177/// A generic type parameter.
178#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
179#[cfg_attr(
180    feature = "serde",
181    serde(bound(
182        serialize = "T::Type: Serialize, T::String: Serialize",
183        deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
184    ))
185)]
186#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
187#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
188#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode)]
189pub struct TypeParameter<T: Form = MetaForm> {
190    /// The name of the generic type parameter e.g. "T".
191    pub name: T::String,
192    /// The concrete type for the type parameter.
193    ///
194    /// `None` if the type parameter is skipped.
195    #[cfg_attr(feature = "serde", serde(rename = "type"))]
196    pub ty: Option<T::Type>,
197}
198
199impl IntoPortable for TypeParameter {
200    type Output = TypeParameter<PortableForm>;
201
202    fn into_portable(self, registry: &mut Registry) -> Self::Output {
203        TypeParameter {
204            name: self.name.into(),
205            ty: self.ty.map(|ty| registry.register_type(&ty)),
206        }
207    }
208}
209
210impl TypeParameter<MetaForm> {
211    /// Create a new [`TypeParameter`].
212    pub fn new(name: <MetaForm as Form>::String, ty: Option<<MetaForm as Form>::Type>) -> Self {
213        Self { name, ty }
214    }
215}
216
217impl TypeParameter<PortableForm> {
218    /// Create a new [`TypeParameter`] in [`PortableForm`].
219    pub fn new_portable(
220        name: <PortableForm as Form>::String,
221        ty: Option<<PortableForm as Form>::Type>,
222    ) -> Self {
223        Self { name, ty }
224    }
225}
226
227impl<T> TypeParameter<T>
228where
229    T: Form,
230{
231    /// Get the type of the parameter.
232    ///
233    /// `None` if the parameter is skipped.
234    #[deprecated(
235        since = "2.5.0",
236        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
237    )]
238    pub fn ty(&self) -> Option<&T::Type> {
239        self.ty.as_ref()
240    }
241
242    /// Get the name of the parameter.
243    #[deprecated(
244        since = "2.5.0",
245        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
246    )]
247    pub fn name(&self) -> &T::String {
248        &self.name
249    }
250}
251
252/// The possible types a SCALE encodable Rust value could have.
253///
254/// # Note
255///
256/// In order to preserve backwards compatibility, variant indices are explicitly specified instead
257/// of depending on the default implicit ordering.
258///
259/// When adding a new variant, it must be added at the end with an incremented index.
260///
261/// When removing an existing variant, the rest of variant indices remain the same, and the removed
262/// index should not be reused.
263#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
264#[cfg_attr(
265    feature = "serde",
266    serde(bound(
267        serialize = "T::Type: Serialize, T::String: Serialize",
268        deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
269    ))
270)]
271#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
272#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
273#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
274#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Encode)]
275pub enum TypeDef<T: Form = MetaForm> {
276    /// A composite type (e.g. a struct or a tuple)
277    #[codec(index = 0)]
278    Composite(TypeDefComposite<T>),
279    /// A variant type (e.g. an enum)
280    #[codec(index = 1)]
281    Variant(TypeDefVariant<T>),
282    /// A sequence type with runtime known length.
283    #[codec(index = 2)]
284    Sequence(TypeDefSequence<T>),
285    /// An array type with compile-time known length.
286    #[codec(index = 3)]
287    Array(TypeDefArray<T>),
288    /// A tuple type.
289    #[codec(index = 4)]
290    Tuple(TypeDefTuple<T>),
291    /// A Rust primitive type.
292    #[codec(index = 5)]
293    Primitive(TypeDefPrimitive),
294    /// A type using the [`Compact`] encoding
295    #[codec(index = 6)]
296    Compact(TypeDefCompact<T>),
297    /// A type representing a sequence of bits.
298    #[codec(index = 7)]
299    BitSequence(TypeDefBitSequence<T>),
300}
301
302macro_rules! impl_from_type_defs {
303    ( $($from:ty => $variant:ident, )* ) => { $(
304        impl<F: Form> From<$from> for TypeDef<F> {
305            fn from(x: $from) -> Self {
306                Self::$variant(x)
307            }
308        }
309    )* }
310}
311
312impl_from_type_defs!(
313    TypeDefComposite<F> => Composite,
314    TypeDefVariant<F> => Variant,
315    TypeDefSequence<F> => Sequence,
316    TypeDefArray<F> => Array,
317    TypeDefTuple<F> => Tuple,
318    TypeDefPrimitive => Primitive,
319    TypeDefCompact<F> => Compact,
320    TypeDefBitSequence<F> => BitSequence,
321);
322
323impl IntoPortable for TypeDef {
324    type Output = TypeDef<PortableForm>;
325
326    fn into_portable(self, registry: &mut Registry) -> Self::Output {
327        match self {
328            TypeDef::Composite(composite) => composite.into_portable(registry).into(),
329            TypeDef::Variant(variant) => variant.into_portable(registry).into(),
330            TypeDef::Sequence(sequence) => sequence.into_portable(registry).into(),
331            TypeDef::Array(array) => array.into_portable(registry).into(),
332            TypeDef::Tuple(tuple) => tuple.into_portable(registry).into(),
333            TypeDef::Primitive(primitive) => primitive.into(),
334            TypeDef::Compact(compact) => compact.into_portable(registry).into(),
335            TypeDef::BitSequence(bitseq) => bitseq.into_portable(registry).into(),
336        }
337    }
338}
339
340/// A primitive Rust type.
341///
342/// # Note
343///
344/// Explicit codec indices specified to ensure backwards compatibility. See [`TypeDef`].
345#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
346#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
347#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
348#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
349#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
350pub enum TypeDefPrimitive {
351    /// `bool` type
352    #[codec(index = 0)]
353    Bool,
354    /// `char` type
355    #[codec(index = 1)]
356    Char,
357    /// `str` type
358    #[codec(index = 2)]
359    Str,
360    /// `u8`
361    #[codec(index = 3)]
362    U8,
363    /// `u16`
364    #[codec(index = 4)]
365    U16,
366    /// `u32`
367    #[codec(index = 5)]
368    U32,
369    /// `u64`
370    #[codec(index = 6)]
371    U64,
372    /// `u128`
373    #[codec(index = 7)]
374    U128,
375    /// 256 bits unsigned int (no rust equivalent)
376    #[codec(index = 8)]
377    U256,
378    /// `i8`
379    #[codec(index = 9)]
380    I8,
381    /// `i16`
382    #[codec(index = 10)]
383    I16,
384    /// `i32`
385    #[codec(index = 11)]
386    I32,
387    /// `i64`
388    #[codec(index = 12)]
389    I64,
390    /// `i128`
391    #[codec(index = 13)]
392    I128,
393    /// 256 bits signed int (no rust equivalent)
394    #[codec(index = 14)]
395    I256,
396}
397
398/// An array type.
399#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
400#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
401#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
402#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
403pub struct TypeDefArray<T: Form = MetaForm> {
404    /// The length of the array type.
405    pub len: u32,
406    /// The element type of the array type.
407    #[cfg_attr(feature = "serde", serde(rename = "type"))]
408    pub type_param: T::Type,
409}
410
411impl IntoPortable for TypeDefArray {
412    type Output = TypeDefArray<PortableForm>;
413
414    fn into_portable(self, registry: &mut Registry) -> Self::Output {
415        TypeDefArray {
416            len: self.len,
417            type_param: registry.register_type(&self.type_param),
418        }
419    }
420}
421
422#[allow(clippy::len_without_is_empty)]
423impl<T> TypeDefArray<T>
424where
425    T: Form,
426{
427    /// Creates a new array type.
428    pub fn new(len: u32, type_param: <T as Form>::Type) -> Self {
429        Self { len, type_param }
430    }
431
432    /// Returns the length of the array type.
433    #[deprecated(
434        since = "2.5.0",
435        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
436    )]
437    pub fn len(&self) -> u32 {
438        self.len
439    }
440
441    /// Returns the element type of the array type.
442    #[deprecated(
443        since = "2.5.0",
444        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
445    )]
446    pub fn type_param(&self) -> &T::Type {
447        &self.type_param
448    }
449}
450
451/// A type to refer to tuple types.
452#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
453#[cfg_attr(
454    feature = "serde",
455    serde(bound(
456        serialize = "T::Type: Serialize, T::String: Serialize",
457        deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
458    ))
459)]
460#[cfg_attr(feature = "serde", serde(transparent))]
461#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
462#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
463#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
464pub struct TypeDefTuple<T: Form = MetaForm> {
465    /// The types of the tuple fields.
466    pub fields: Vec<T::Type>,
467}
468
469impl IntoPortable for TypeDefTuple {
470    type Output = TypeDefTuple<PortableForm>;
471
472    fn into_portable(self, registry: &mut Registry) -> Self::Output {
473        TypeDefTuple {
474            fields: registry.register_types(self.fields),
475        }
476    }
477}
478
479impl TypeDefTuple {
480    /// Creates a new tuple type definition from the given types.
481    pub fn new<T>(type_params: T) -> Self
482    where
483        T: IntoIterator<Item = MetaType>,
484    {
485        Self {
486            fields: type_params
487                .into_iter()
488                .filter(|ty| !ty.is_phantom())
489                .collect(),
490        }
491    }
492
493    /// Creates a new unit tuple to represent the unit type, `()`.
494    pub fn unit() -> Self {
495        Self::new(vec![])
496    }
497}
498
499impl TypeDefTuple<PortableForm> {
500    /// Creates a new custom type definition from the given types.
501    pub fn new_portable<I>(type_params: I) -> Self
502    where
503        I: IntoIterator<Item = <PortableForm as Form>::Type>,
504    {
505        Self {
506            fields: type_params.into_iter().collect(),
507        }
508    }
509}
510
511impl<T> TypeDefTuple<T>
512where
513    T: Form,
514{
515    /// Returns the types of the tuple fields.
516    #[deprecated(
517        since = "2.5.0",
518        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
519    )]
520    pub fn fields(&self) -> &[T::Type] {
521        &self.fields
522    }
523}
524
525/// A type to refer to a sequence of elements of the same type.
526#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
527#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
528#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
529#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
530pub struct TypeDefSequence<T: Form = MetaForm> {
531    /// The element type of the sequence type.
532    #[cfg_attr(feature = "serde", serde(rename = "type"))]
533    pub type_param: T::Type,
534}
535
536impl IntoPortable for TypeDefSequence {
537    type Output = TypeDefSequence<PortableForm>;
538
539    fn into_portable(self, registry: &mut Registry) -> Self::Output {
540        TypeDefSequence {
541            type_param: registry.register_type(&self.type_param),
542        }
543    }
544}
545
546impl TypeDefSequence {
547    /// Creates a new sequence type.
548    ///
549    /// Use this constructor if you want to instantiate from a given
550    /// compile-time type.
551    pub fn of<T>() -> Self
552    where
553        T: TypeInfo + 'static,
554    {
555        Self::new(MetaType::new::<T>())
556    }
557}
558
559impl<T> TypeDefSequence<T>
560where
561    T: Form,
562{
563    /// Creates a new sequence type.
564    ///
565    /// Use this constructor if you want to instantiate from a given meta type.
566    pub fn new(type_param: <T as Form>::Type) -> Self {
567        Self { type_param }
568    }
569
570    /// Returns the element type of the sequence type.
571    #[deprecated(
572        since = "2.5.0",
573        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
574    )]
575    pub fn type_param(&self) -> &T::Type {
576        &self.type_param
577    }
578}
579
580/// A type wrapped in [`Compact`].
581#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
582#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
583#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
584#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
585pub struct TypeDefCompact<T: Form = MetaForm> {
586    /// The type wrapped in [`Compact`], i.e. the `T` in `Compact<T>`.
587    #[cfg_attr(feature = "serde", serde(rename = "type"))]
588    pub type_param: T::Type,
589}
590
591impl IntoPortable for TypeDefCompact {
592    type Output = TypeDefCompact<PortableForm>;
593
594    fn into_portable(self, registry: &mut Registry) -> Self::Output {
595        TypeDefCompact {
596            type_param: registry.register_type(&self.type_param),
597        }
598    }
599}
600
601impl<T> TypeDefCompact<T>
602where
603    T: Form,
604{
605    /// Creates a new type wrapped in [`Compact`].
606    pub fn new(type_param: <T as Form>::Type) -> Self {
607        Self { type_param }
608    }
609
610    /// Returns the [`Compact`] wrapped type, i.e. the `T` in `Compact<T>`.
611    #[deprecated(
612        since = "2.5.0",
613        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
614    )]
615    pub fn type_param(&self) -> &T::Type {
616        &self.type_param
617    }
618}
619
620/// Type describing a [`bitvec::vec::BitVec`].
621///
622/// # Note
623///
624/// This can only be constructed for `TypeInfo` in the `MetaForm` with the `bit-vec` feature
625/// enabled, but can be decoded or deserialized into the `PortableForm` without this feature.
626#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
627#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
628#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
629#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
630pub struct TypeDefBitSequence<T: Form = MetaForm> {
631    /// The type implementing [`bitvec::store::BitStore`].
632    pub bit_store_type: T::Type,
633    /// The type implementing [`bitvec::order::BitOrder`].
634    pub bit_order_type: T::Type,
635}
636
637impl IntoPortable for TypeDefBitSequence {
638    type Output = TypeDefBitSequence<PortableForm>;
639
640    fn into_portable(self, registry: &mut Registry) -> Self::Output {
641        TypeDefBitSequence {
642            bit_store_type: registry.register_type(&self.bit_store_type),
643            bit_order_type: registry.register_type(&self.bit_order_type),
644        }
645    }
646}
647
648impl<T> TypeDefBitSequence<T>
649where
650    T: Form,
651{
652    /// Returns the type of the bit ordering of the [`::bitvec::vec::BitVec`].
653    #[deprecated(
654        since = "2.5.0",
655        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
656    )]
657    pub fn bit_order_type(&self) -> &T::Type {
658        &self.bit_order_type
659    }
660
661    /// Returns underlying type used to store the [`::bitvec::vec::BitVec`].
662    #[deprecated(
663        since = "2.5.0",
664        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
665    )]
666    pub fn bit_store_type(&self) -> &T::Type {
667        &self.bit_store_type
668    }
669}
670
671impl TypeDefBitSequence {
672    /// Creates a new [`TypeDefBitSequence`] for the supplied bit order and bit store types.
673    ///
674    /// With the `bit-vec` feature enabled, the expected usage is to provide either
675    /// `bitvec::order::Lsb0` or `bitvec::order::Msb0` as the order type, and then something
676    /// like u8, u8, or u32 as the store type. Without the `bit-vec` feature enabled, it's
677    /// recommended that your types have identical `TypeInfo` to those.
678    pub fn new<Store, Order>() -> Self
679    where
680        Store: TypeInfo + 'static,
681        Order: TypeInfo + 'static,
682    {
683        Self {
684            bit_store_type: MetaType::new::<Store>(),
685            bit_order_type: MetaType::new::<Order>(),
686        }
687    }
688}
689
690impl TypeDefBitSequence<PortableForm> {
691    /// Creates a new [`TypeDefBitSequence`] for the supplied bit order and bit store types.
692    pub fn new_portable(
693        bit_store_type: <PortableForm as Form>::Type,
694        bit_order_type: <PortableForm as Form>::Type,
695    ) -> Self {
696        Self {
697            bit_store_type,
698            bit_order_type,
699        }
700    }
701}