use crate::tm_std::*;
use crate::{
build::TypeBuilder,
form::{CompactForm, Form, MetaForm},
IntoCompact, MetaType, Registry, TypeInfo,
};
use derive_more::From;
use scale::{Decode, Encode};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
mod composite;
mod fields;
mod path;
mod variant;
pub use self::{composite::*, fields::*, path::*, variant::*};
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Serialize, Deserialize, Encode, Decode)]
#[serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned"
))]
pub struct Type<T: Form = MetaForm> {
#[serde(skip_serializing_if = "Path::is_empty", default)]
path: Path<T>,
#[serde(rename = "params", skip_serializing_if = "Vec::is_empty", default)]
type_params: Vec<T::Type>,
#[serde(rename = "def")]
type_def: TypeDef<T>,
}
impl IntoCompact for Type {
type Output = Type<CompactForm>;
fn into_compact(self, registry: &mut Registry) -> Self::Output {
Type {
path: self.path.into_compact(registry),
type_params: registry.register_types(self.type_params),
type_def: self.type_def.into_compact(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 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
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Serialize, Deserialize, Encode, Decode)]
#[serde(bound(
serialize = "T::Type: Serialize, T::String: Serialize",
deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned"
))]
#[serde(rename_all = "camelCase")]
pub enum TypeDef<T: Form = MetaForm> {
Composite(TypeDefComposite<T>),
Variant(TypeDefVariant<T>),
Sequence(TypeDefSequence<T>),
Array(TypeDefArray<T>),
Tuple(TypeDefTuple<T>),
Primitive(TypeDefPrimitive),
}
impl IntoCompact for TypeDef {
type Output = TypeDef<CompactForm>;
fn into_compact(self, registry: &mut Registry) -> Self::Output {
match self {
TypeDef::Composite(composite) => composite.into_compact(registry).into(),
TypeDef::Variant(variant) => variant.into_compact(registry).into(),
TypeDef::Sequence(sequence) => sequence.into_compact(registry).into(),
TypeDef::Array(array) => array.into_compact(registry).into(),
TypeDef::Tuple(tuple) => tuple.into_compact(registry).into(),
TypeDef::Primitive(primitive) => primitive.into(),
}
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize, Encode, Decode, Debug)]
#[serde(rename_all = "lowercase")]
pub enum TypeDefPrimitive {
Bool,
Char,
Str,
U8,
U16,
U32,
U64,
U128,
I8,
I16,
I32,
I64,
I128,
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize, Encode, Decode, Debug)]
#[serde(bound(serialize = "T::Type: Serialize", deserialize = "T::Type: DeserializeOwned"))]
pub struct TypeDefArray<T: Form = MetaForm> {
len: u32,
#[serde(rename = "type")]
type_param: T::Type,
}
impl IntoCompact for TypeDefArray {
type Output = TypeDefArray<CompactForm>;
fn into_compact(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
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize, Encode, Decode, Debug)]
#[serde(bound(serialize = "T::Type: Serialize", deserialize = "T::Type: DeserializeOwned"))]
#[serde(transparent)]
pub struct TypeDefTuple<T: Form = MetaForm> {
fields: Vec<T::Type>,
}
impl IntoCompact for TypeDefTuple {
type Output = TypeDefTuple<CompactForm>;
fn into_compact(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
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize, Encode, Decode, Debug)]
#[serde(bound(serialize = "T::Type: Serialize", deserialize = "T::Type: DeserializeOwned"))]
pub struct TypeDefSequence<T: Form = MetaForm> {
#[serde(rename = "type")]
type_param: T::Type,
}
impl IntoCompact for TypeDefSequence {
type Output = TypeDefSequence<CompactForm>;
fn into_compact(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
}
}