// Copyright 2019-2021 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Efficient and space-efficient serialization of Rust types.
//!
//! This library provides structures to easily retrieve compile-time type
//! information at runtime and also to serialize this information in a
//! space-efficient form, aka `PortableForm`.
//!
//! # Registry
//!
//! At the heart of its functionality is the [`Registry`](`crate::Registry`)
//! that acts as a cache for known types in order to efficiently deduplicate
//! types and ensure a space-efficient serialization.
//!
//! # Type Information
//!
//! Information about types is provided via the [`TypeInfo`](`crate::TypeInfo`)
//! trait.
//!
//! This trait should be implemented for all types that are serializable.
//! `tetsy-scale-info` provides implementations for all commonly used Rust standard
//! types and a derive macro for implementing of custom types.
//!
//! # Forms
//!
//! To bridge between compile-time type information and runtime the
//! [`MetaForm`](`crate::form::MetaForm`) is used to easily retrieve all
//! information needed to uniquely identify types.
//!
//! The `MetaForm` and its associated `Registry` can be transformed into the
//! space-efficient form by the [`IntoPortable`](`crate::IntoPortable`) trait; it is
//! used internally by the [`Registry`](`crate::Registry`) in order to convert
//! the expanded types into their space-efficient form.
//!
//! # Symbols and Namespaces
//!
//! To differentiate two types sharing the same name, namespaces are used.
//! Commonly the namespace is equal to the one where the type has been defined
//! in. For Rust prelude types such as [`Option`](`std::option::Option`) and
//! [`Result`](`std::result::Result`) the root namespace (empty namespace) is
//! used.
//!
//! To use this library simply use the [`MetaForm`](`crate::form::MetaForm`)
//! initially with your own data structures; make them generic over the
//! [`Form`](`crate::form::Form`) trait just as has been done in this crate with
//! [`TypeInfo`](`crate::TypeInfo`) in order to get a simple implementation of
//! [`IntoPortable`](`crate::IntoPortable`). Use a single instance of the
//! [`Registry`](`crate::Registry`) for compaction and provide this registry
//! instance upon serialization.
//!
//! A usage example can be found in ink! here:
//! https://github.com/paritytech/ink/blob/master/abi/src/specs.rs
/// Takes a number of types and returns a vector that contains their respective
/// [`MetaType`](`crate::MetaType`) instances.
///
/// This is useful for places that require inputs of iterators over [`MetaType`](`crate::MetaType`)
/// instances and provide a way out of code bloat in these scenarious.
///
/// # Example
///
/// ```
/// # use tetsy_scale_info::tuple_meta_type;
/// assert_eq!(
/// tuple_meta_type!(i32, [u8; 32], String),
/// {
/// use tetsy_scale_info::MetaType;
/// let mut vec = Vec::new();
/// vec.push(MetaType::new::<i32>());
/// vec.push(MetaType::new::<[u8; 32]>());
/// vec.push(MetaType::new::<String>());
/// vec
/// }
/// );
/// ```
pub use ;
pub use TypeInfo;
/// Implementors return their meta type information.
/// Returns the runtime bridge to the types compile-time type information.