use crate::prelude::{
vec,
vec::Vec,
};
use crate::{
build::TypeBuilder,
form::{
Form,
MetaForm,
PortableForm,
},
IntoPortable,
MetaType,
Registry,
TypeInfo,
};
use derive_more::From;
use scale::{
Decode,
Encode,
};
#[cfg(feature = "serde")]
use serde::{
de::DeserializeOwned,
Deserialize,
Serialize,
};
mod composite;
mod fields;
mod path;
mod variant;
pub use self::{
composite::*,
fields::*,
path::*,
variant::*,
};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
))
)]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode, Decode)]
pub struct Type<T: Form = MetaForm> {
#[cfg_attr(
feature = "serde",
serde(skip_serializing_if = "Path::is_empty", default)
)]
path: Path<T>,
#[cfg_attr(
feature = "serde",
serde(rename = "params", skip_serializing_if = "Vec::is_empty", default)
)]
type_params: Vec<T::Type>,
#[cfg_attr(feature = "serde", serde(rename = "def"))]
type_def: TypeDef<T>,
}
impl IntoPortable for Type {
type Output = Type<PortableForm>;
fn into_portable(self, registry: &mut Registry) -> Self::Output {
Type {
path: self.path.into_portable(registry),
type_params: registry.register_types(self.type_params),
type_def: self.type_def.into_portable(registry),
}
}
}
impl From<TypeDefPrimitive> for Type {
fn from(primitive: TypeDefPrimitive) -> Self {
Self::new(Path::voldemort(), Vec::new(), primitive)
}
}
impl From<TypeDefArray> for Type {
fn from(array: TypeDefArray) -> Self {
Self::new(Path::voldemort(), Vec::new(), array)
}
}
impl From<TypeDefSequence> for Type {
fn from(sequence: TypeDefSequence) -> Self {
Self::new(Path::voldemort(), Vec::new(), sequence)
}
}
impl From<TypeDefTuple> for Type {
fn from(tuple: TypeDefTuple) -> Self {
Self::new(Path::voldemort(), Vec::new(), tuple)
}
}
impl From<TypeDefPhantom> for Type {
fn from(phantom: TypeDefPhantom) -> Self {
Self::new(Path::voldemort(), Vec::new(), phantom)
}
}
impl Type {
pub fn builder() -> TypeBuilder {
TypeBuilder::default()
}
pub(crate) fn new<I, D>(path: Path, type_params: I, type_def: D) -> Self
where
I: IntoIterator<Item = MetaType>,
D: Into<TypeDef>,
{
Self {
path,
type_params: type_params.into_iter().collect(),
type_def: type_def.into(),
}
}
}
impl<T> Type<T>
where
T: Form,
{
pub fn path(&self) -> &Path<T> {
&self.path
}
pub fn type_params(&self) -> &[T::Type] {
&self.type_params
}
pub fn type_def(&self) -> &TypeDef<T> {
&self.type_def
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
))
)]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode, Decode)]
pub enum TypeDef<T: Form = MetaForm> {
Composite(TypeDefComposite<T>),
Variant(TypeDefVariant<T>),
Sequence(TypeDefSequence<T>),
Array(TypeDefArray<T>),
Tuple(TypeDefTuple<T>),
Primitive(TypeDefPrimitive),
Phantom(TypeDefPhantom<T>),
}
impl IntoPortable for TypeDef {
type Output = TypeDef<PortableForm>;
fn into_portable(self, registry: &mut Registry) -> Self::Output {
match self {
TypeDef::Composite(composite) => composite.into_portable(registry).into(),
TypeDef::Variant(variant) => variant.into_portable(registry).into(),
TypeDef::Sequence(sequence) => sequence.into_portable(registry).into(),
TypeDef::Array(array) => array.into_portable(registry).into(),
TypeDef::Tuple(tuple) => tuple.into_portable(registry).into(),
TypeDef::Primitive(primitive) => primitive.into(),
TypeDef::Phantom(phantom) => phantom.into_portable(registry).into(),
}
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum TypeDefPrimitive {
Bool,
Char,
Str,
U8,
U16,
U32,
U64,
U128,
U256,
I8,
I16,
I32,
I64,
I128,
I256,
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
))
)]
pub struct TypeDefArray<T: Form = MetaForm> {
len: u32,
#[cfg_attr(feature = "serde", serde(rename = "type"))]
type_param: T::Type,
}
impl IntoPortable for TypeDefArray {
type Output = TypeDefArray<PortableForm>;
fn into_portable(self, registry: &mut Registry) -> Self::Output {
TypeDefArray {
len: self.len,
type_param: registry.register_type(&self.type_param),
}
}
}
impl TypeDefArray {
pub fn new(len: u32, type_param: MetaType) -> Self {
Self { len, type_param }
}
}
#[allow(clippy::len_without_is_empty)]
impl<T> TypeDefArray<T>
where
T: Form,
{
pub fn len(&self) -> u32 {
self.len
}
pub fn type_param(&self) -> &T::Type {
&self.type_param
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
))
)]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)]
pub struct TypeDefTuple<T: Form = MetaForm> {
fields: Vec<T::Type>,
}
impl IntoPortable for TypeDefTuple {
type Output = TypeDefTuple<PortableForm>;
fn into_portable(self, registry: &mut Registry) -> Self::Output {
TypeDefTuple {
fields: registry.register_types(self.fields),
}
}
}
impl TypeDefTuple {
pub fn new<T>(type_params: T) -> Self
where
T: IntoIterator<Item = MetaType>,
{
Self {
fields: type_params.into_iter().collect(),
}
}
pub fn unit() -> Self {
Self::new(vec![])
}
}
impl<T> TypeDefTuple<T>
where
T: Form,
{
pub fn fields(&self) -> &[T::Type] {
&self.fields
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
))
)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)]
pub struct TypeDefSequence<T: Form = MetaForm> {
#[cfg_attr(feature = "serde", serde(rename = "type"))]
type_param: T::Type,
}
impl IntoPortable for TypeDefSequence {
type Output = TypeDefSequence<PortableForm>;
fn into_portable(self, registry: &mut Registry) -> Self::Output {
TypeDefSequence {
type_param: registry.register_type(&self.type_param),
}
}
}
impl TypeDefSequence {
pub fn new(type_param: MetaType) -> Self {
Self { type_param }
}
pub fn of<T>() -> Self
where
T: TypeInfo + 'static,
{
Self::new(MetaType::new::<T>())
}
}
impl<T> TypeDefSequence<T>
where
T: Form,
{
pub fn type_param(&self) -> &T::Type {
&self.type_param
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "T::Type: Serialize",
deserialize = "T::Type: DeserializeOwned",
))
)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)]
pub struct TypeDefPhantom<T: Form = MetaForm> {
#[cfg_attr(feature = "serde", serde(rename = "type"))]
type_param: T::Type,
}
impl IntoPortable for TypeDefPhantom {
type Output = TypeDefPhantom<PortableForm>;
fn into_portable(self, registry: &mut Registry) -> Self::Output {
TypeDefPhantom {
type_param: registry.register_type(&self.type_param),
}
}
}
impl TypeDefPhantom {
pub fn new(type_param: MetaType) -> Self {
Self { type_param }
}
}
impl<T> TypeDefPhantom<T>
where
T: Form,
{
pub fn type_param(&self) -> &T::Type {
&self.type_param
}
}