scale-info ยท
A library to describe Rust types, geared towards providing info about the structure of SCALE encodable types.
The definitions provide third party tools (e.g. a UI client) with information about how they are able to decode types agnostic of language.
At its core is the TypeInfo
trait:
Types implementing this trait build up and return a Type
struct:
Types are defined as one of the following variants:
Built-in Type Definitions
The following "built-in" types have predefined TypeInfo
definitions:
-
Primitives:
bool
,char
,str
,u8
,u16
,u32
,u64
,u128
,i8
,i16
,i32
,i64
,i128
. -
Sequence: Variable size sequence of elements of
T
, whereT
implementsTypeInfo
. e.g.[T]
,&[T]
,&mut [T]
,Vec<T>
-
Array: Fixed size
[T: $n]
for anyT
which implementsTypeInfo
, where$n
is one of the predefined sizes. -
Tuple: Tuples consisting of up to 10 fields with types implementing
TypeInfo
.
User-defined Types
There are two kinds of user-defined types: Composite
and Variant
.
Both make use of the Path
and Field
types in their definition:
Fields
A fundamental building block to represent user defined types is the Field
struct which defines the Type
of a
field together with its optional name. Builders for the user defined types enforce the invariant that either all
fields have a name (e.g. structs) or all fields are unnamed (e.g. tuples).
Path
The path of a type is a unique sequence of identifiers. Rust types typically construct a path from
the namespace and the identifier e.g. foo::bar::Baz
is converted to the path ["foo", "bar ", "Baz"]
.
Composite
Composite data types are composed of a set of Fields
.
Structs are represented by a set of named fields, enforced during construction:
Tuples are represented by a set of unnamed fields, enforced during construction:
;
Variant
Variant types aka enums or tagged unions are composed of a set of variants. Variants can have unnamed fields, named fields or no fields at all:
If all variants contain no fields then the discriminant can be set explicitly, enforced by the builder during construction:
The Registry
Information about types is provided within the so-called type registry (Registry
).
Type definitions are registered there and are associated with unique IDs that the outside
can use to refer to them providing a lightweight way to decrease overhead instead of using type
identifiers.
All concrete TypeInfo
structures have two forms:
One meta form (MetaType
) that acts as a bridge to other forms and a compact form that is later
to be serialized. The IntoCompact
trait is implemented by them in order to compact a type
definition using an instance of a type registry.
After compactification all type definitions are stored in the type registry. Note that the type registry should be serialized as part of the metadata structure where the registered types are utilized to allow consumers to resolve the types.
Serialization
Currently the only supported serialization format is JSON, an example of which can be found here.
Future support for binary formats is planned, either SCALE itself or a more compressed format where the monomorphization of Rust generic types could potentially result in very large files.
Resources
- See usage for describing types for
ink!
smart contracts metadata. - Original design draft (outdated)