{"id":19358360,"url":"https://github.com/paritytech/scale-info","last_synced_at":"2025-05-15T09:07:54.407Z","repository":{"id":37096794,"uuid":"248465758","full_name":"paritytech/scale-info","owner":"paritytech","description":"Info about SCALE encodable Rust types","archived":false,"fork":false,"pushed_at":"2025-02-19T16:43:01.000Z","size":956,"stargazers_count":73,"open_issues_count":20,"forks_count":30,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-05-15T00:16:58.959Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paritytech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-19T09:48:51.000Z","updated_at":"2025-04-04T04:33:49.000Z","dependencies_parsed_at":"2024-02-02T10:50:20.972Z","dependency_job_id":"79d5efa6-0552-410b-b6c6-d3fd2f32b360","html_url":"https://github.com/paritytech/scale-info","commit_stats":{"total_commits":308,"total_committers":21,"mean_commits":"14.666666666666666","dds":0.5974025974025974,"last_synced_commit":"caa38cbb6256ae7ebdccc23d35a7633d4f43c2bd"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paritytech%2Fscale-info","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paritytech%2Fscale-info/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paritytech%2Fscale-info/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paritytech%2Fscale-info/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paritytech","download_url":"https://codeload.github.com/paritytech/scale-info/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254310515,"owners_count":22049469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T07:11:24.322Z","updated_at":"2025-05-15T09:07:49.398Z","avatar_url":"https://github.com/paritytech.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# scale-info \u0026middot; [![build][a1]][a2] [![Latest Version][b1]][b2]\n\n[a1]: https://github.com/paritytech/scale-info/workflows/Rust/badge.svg\n[a2]: https://github.com/paritytech/scale-info/actions?query=workflow%3ARust+branch%3Amaster\n[b1]: https://img.shields.io/crates/v/scale-info.svg\n[b2]: https://crates.io/crates/scale-info\n\nA library to describe Rust types, geared towards providing info about the structure of [SCALE\n](https://github.com/paritytech/parity-scale-codec) encodable types.\n\nThe definitions provide third party tools (e.g. a UI client) with information about how they\nare able to decode types agnostic of language.\n\nAt its core is the `TypeInfo` trait:\n\n```rust\npub trait TypeInfo {\n    type Identity: ?Sized + 'static;\n    fn type_info() -\u003e Type;\n}\n```\n\nTypes implementing this trait build up and return a `Type` struct:\n\n```rust\npub struct Type\u003cT: Form = MetaForm\u003e {\n    /// The unique path to the type. Can be empty for built-in types\n    path: Path\u003cT\u003e,\n    /// The generic type parameters of the type in use. Empty for non generic types\n    type_params: Vec\u003cT::Type\u003e,\n    /// The actual type definition\n    type_def: TypeDef\u003cT\u003e,\n}\n```\nTypes are defined as one of the following variants:\n```rust\npub enum TypeDef\u003cT: Form = MetaForm\u003e {\n    /// A composite type (e.g. a struct or a tuple)\n    Composite(TypeDefComposite\u003cT\u003e),\n    /// A variant type (e.g. an enum)\n    Variant(TypeDefVariant\u003cT\u003e),\n    /// A sequence type with runtime known length.\n    Sequence(TypeDefSequence\u003cT\u003e),\n    /// An array type with compile-time known length.\n    Array(TypeDefArray\u003cT\u003e),\n    /// A tuple type.\n    Tuple(TypeDefTuple\u003cT\u003e),\n    /// A Rust primitive type.\n    Primitive(TypeDefPrimitive),\n}\n```\n\n## Built-in Type Definitions\n\nThe following \"built-in\" types have predefined `TypeInfo` definitions:\n\n- **Primitives:** `bool`, `char`, `str`, `u8`, `u16`, `u32`, `u64`, `u128`, `i8`, `i16`, `i32`, `i64`, `i128`.\n\n- **Sequence:** Variable size sequence of elements of `T`, where `T` implements `TypeInfo`. e.g. `[T]`, `\u0026[T]`, `\u0026mut\n [T]`, `Vec\u003cT\u003e`\n\n- **Array:** Fixed size `[T: $n]` for any `T` which implements `TypeInfo`, where `$n` is one of the\n predefined sizes.\n\n- **Tuple:** Tuples consisting of up to 10 fields with types implementing `TypeInfo`.\n\n## User-defined Types\n\nThere are two kinds of user-defined types: `Composite` and `Variant`.\n\nBoth make use of the `Path` and `Field` types in their definition:\n\n### Fields\n\nA fundamental building block to represent user defined types is the `Field` struct which defines the `Type` of a\nfield together with its optional name. Builders for the user defined types enforce the invariant that either all\nfields have a name (e.g. structs) or all fields are unnamed (e.g. tuples).\n\n### Path\n\nThe path of a type is a unique sequence of identifiers. Rust types typically construct a path from\nthe namespace and the identifier e.g. `foo::bar::Baz` is converted to the path `[\"foo\", \"bar\", \n\"Baz\"]`.\n\n### Composite\n\n[Composite data types](https://en.wikipedia.org/wiki/Composite_data_type) are composed of a set of `Fields`.\n\n**Structs** are represented by a set of *named* fields, enforced during construction:\n\n```rust\nstruct Foo\u003cT\u003e {\n    bar: T,\n    data: u64,\n}\n\nimpl\u003cT\u003e TypeInfo for Foo\u003cT\u003e\nwhere\n    T: TypeInfo + 'static,\n{\n    type Identity = Self;\n\n    fn type_info() -\u003e Type {\n        Type::builder()\n            .path(Path::new(\"Foo\", module_path!()))\n            .type_params(vec![MetaType::new::\u003cT\u003e()])\n            .composite(Fields::named()\n                .field(|f| f.ty::\u003cT\u003e().name(\"bar\").type_name(\"T\"))\n                .field(|f| f.ty::\u003cu64\u003e().name(\"data\").type_name(\"u64\"))\n            )\n    }\n}\n```\n\n**Tuples** are represented by a set of *unnamed* fields, enforced during construction:\n\n```rust\nstruct Foo(u32, bool);\n\nimpl TypeInfo for Foo {\n    type Identity = Self;\n\n    fn type_info() -\u003e Type {\n        Type::builder()\n            .path(Path::new(\"Foo\", module_path!()))\n            .composite(Fields::unnamed()\n                .field(|f| f.ty::\u003cu32\u003e().type_name(\"u32\"))\n                .field(|f| f.ty::\u003cbool\u003e().type_name(\"bool\"))\n            )\n    }\n}\n```\n\n### Variant\n\n[Variant types](https://en.wikipedia.org/wiki/Tagged_union) aka enums or tagged unions are\ncomposed of a set of variants. Variants can have unnamed fields, named fields or no fields at all:\n\n```rust\nenum Foo\u003cT\u003e{\n    A(T),\n    B { f: u32 },\n    C,\n}\n\nimpl\u003cT\u003e TypeInfo for Foo\u003cT\u003e\nwhere\n    T: TypeInfo + 'static,\n{\n    type Identity = Self;\n\n    fn type_info() -\u003e Type {\n        Type::builder()\n            .path(Path::new(\"Foo\", module_path!()))\n            .type_params(vec![MetaType::new::\u003cT\u003e()])\n            .variant(\n                Variants::new()\n                   .variant(\"A\", |v| v.fields(Fields::unnamed().field(|f| f.ty::\u003cT\u003e())))\n                   .variant(\"B\", |v| v.fields(Fields::named().field(|f| f.ty::\u003cu32\u003e().name(\"f\").type_name(\"u32\"))))\n                   .variant_unit(\"C\")\n            )\n    }\n}\n```\n\nIf no variants contain fields then the discriminant can be set explicitly, enforced by the\nbuilder during construction:\n\n```rust\nenum Foo {\n    A,\n    B,\n    C = 33,\n}\n\nimpl TypeInfo for Foo {\n    type Identity = Self;\n\n    fn type_info() -\u003e Type {\n        Type::builder()\n            .path(Path::new(\"Foo\", module_path!()))\n            .variant(\n                Variants::new()\n                    .variant(\"A\", |v| v.index(1))\n                    .variant(\"B\", |v| v.index(2))\n                    .variant(\"C\", |v| v.index(33))\n            )\n    }\n}\n```\n\n## The Registry\n\nInformation about types is provided within the so-called type registry (`Registry`).\nType definitions are registered there and are associated with unique IDs that the outside\ncan refer to, providing a lightweight way to decrease overhead instead of using type\nidentifiers.\n\nAll concrete `TypeInfo` structures have two forms:\n\n- One meta form (`MetaType`) that acts as a bridge to other forms\n- A portable form suitable for serialization.\n\nThe `IntoPortable` trait must also be implemented in order prepare a type\ndefinition for serialization using an instance of the type registry.\n\nAfter transformation all type definitions are stored in the type registry.\nNote that the type registry should be serialized as part of the metadata structure where the\nregistered types are utilized to allow consumers to resolve the types.\n\n## Encoding\n\nThe type registry can be encoded as:\n\n- JSON (with the \"serde\" feature enabled).\n- SCALE itself (using `parity-scale-codec`).\n\n## Features\n\nThe following optional `cargo` features are available:\n\n- **serde** includes support for json serialization/deserialization of the type registry. See example [here](https://github.com/paritytech/scale-info/blob/master/test_suite/tests/json.rs).\n- **derive** reexports the [`scale-info-derive`](https://crates.io/crates/scale-info-derive) crate.\n\n## Known issues\n\nWhen deriving `TypeInfo` for a type with generic compact fields e.g.\n\n```rust\n#[derive(Encode, TypeInfo)]\nstruct Foo\u003cS\u003e { #[codec(compact)] a: S }\n```\n\nYou may experience the following error when using this generic type without the correct bounds:\n\n```sh\nerror[E0275]: overflow evaluating the requirement `_::_parity_scale_codec::Compact\u003c_\u003e: Decode`\n```\n\nSee https://github.com/paritytech/scale-info/issues/65 for more information.\n\n## Resources\n\n- See usage for describing types for [`ink!`](https://github.com/paritytech/ink/blob/master/crates/metadata/src/specs.rs) smart contracts metadata.\n- [Original design draft (*outdated*)](https://hackmd.io/0wWm0ueBSF26m2pBG5NaeQ?view)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparitytech%2Fscale-info","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparitytech%2Fscale-info","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparitytech%2Fscale-info/lists"}