1use crate::prelude::{vec, vec::Vec};
16
17use crate::{
18 build::TypeBuilder,
19 form::{Form, MetaForm, PortableForm},
20 IntoPortable, MetaType, Registry, TypeInfo,
21};
22use derive_more::From;
23use scale::Encode;
24#[cfg(feature = "serde")]
25use serde::{de::DeserializeOwned, Deserialize, Serialize};
26
27mod composite;
28mod fields;
29mod path;
30mod variant;
31
32pub use self::{composite::*, fields::*, path::*, variant::*};
33
34#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36#[cfg_attr(
37 feature = "serde",
38 serde(bound(
39 serialize = "T::Type: Serialize, T::String: Serialize",
40 deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
41 ))
42)]
43#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
44#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
45#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
46#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode)]
47pub struct Type<T: Form = MetaForm> {
48 #[cfg_attr(
50 feature = "serde",
51 serde(skip_serializing_if = "Path::is_empty", default)
52 )]
53 pub path: Path<T>,
54 #[cfg_attr(
56 feature = "serde",
57 serde(rename = "params", skip_serializing_if = "Vec::is_empty", default)
58 )]
59 pub type_params: Vec<TypeParameter<T>>,
60 #[cfg_attr(feature = "serde", serde(rename = "def"))]
62 pub type_def: TypeDef<T>,
63 #[cfg_attr(
65 feature = "serde",
66 serde(skip_serializing_if = "Vec::is_empty", default)
67 )]
68 pub docs: Vec<T::String>,
69}
70
71impl IntoPortable for Type {
72 type Output = Type<PortableForm>;
73
74 fn into_portable(self, registry: &mut Registry) -> Self::Output {
75 Type {
76 path: self.path.into_portable(registry),
77 type_params: registry.map_into_portable(self.type_params),
78 type_def: self.type_def.into_portable(registry),
79 docs: self.docs.into_iter().map(Into::into).collect(),
80 }
81 }
82}
83
84macro_rules! impl_from_type_def_for_type {
85 ( $( $t:ty ), + $(,)?) => { $(
86 impl<F: Form> From<$t> for Type<F> {
87 fn from(item: $t) -> Self {
88 Self::new(Path::voldemort(), Vec::new(), item, Vec::new())
89 }
90 }
91 )* }
92}
93
94impl_from_type_def_for_type!(
95 TypeDefPrimitive,
96 TypeDefArray<F>,
97 TypeDefSequence<F>,
98 TypeDefTuple<F>,
99 TypeDefCompact<F>,
100 TypeDefBitSequence<F>,
101);
102
103impl Type {
104 pub fn builder() -> TypeBuilder {
107 TypeBuilder::default()
108 }
109
110 pub fn builder_portable() -> TypeBuilder<PortableForm> {
113 TypeBuilder::default()
114 }
115}
116
117impl<F> Type<F>
118where
119 F: Form,
120{
121 pub fn new<I, D>(path: Path<F>, type_params: I, type_def: D, docs: Vec<F::String>) -> Type<F>
123 where
124 I: IntoIterator<Item = TypeParameter<F>>,
125 D: Into<TypeDef<F>>,
126 {
127 Self {
128 path,
129 type_params: type_params.into_iter().collect(),
130 type_def: type_def.into(),
131 docs,
132 }
133 }
134}
135
136impl<T> Type<T>
137where
138 T: Form,
139{
140 #[deprecated(
142 since = "2.5.0",
143 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
144 )]
145 pub fn path(&self) -> &Path<T> {
146 &self.path
147 }
148
149 #[deprecated(
151 since = "2.5.0",
152 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
153 )]
154 pub fn type_params(&self) -> &[TypeParameter<T>] {
155 &self.type_params
156 }
157
158 #[deprecated(
160 since = "2.5.0",
161 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
162 )]
163 pub fn type_def(&self) -> &TypeDef<T> {
164 &self.type_def
165 }
166
167 #[deprecated(
169 since = "2.5.0",
170 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
171 )]
172 pub fn docs(&self) -> &[T::String] {
173 &self.docs
174 }
175}
176
177#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
179#[cfg_attr(
180 feature = "serde",
181 serde(bound(
182 serialize = "T::Type: Serialize, T::String: Serialize",
183 deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
184 ))
185)]
186#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
187#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
188#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode)]
189pub struct TypeParameter<T: Form = MetaForm> {
190 pub name: T::String,
192 #[cfg_attr(feature = "serde", serde(rename = "type"))]
196 pub ty: Option<T::Type>,
197}
198
199impl IntoPortable for TypeParameter {
200 type Output = TypeParameter<PortableForm>;
201
202 fn into_portable(self, registry: &mut Registry) -> Self::Output {
203 TypeParameter {
204 name: self.name.into(),
205 ty: self.ty.map(|ty| registry.register_type(&ty)),
206 }
207 }
208}
209
210impl TypeParameter<MetaForm> {
211 pub fn new(name: <MetaForm as Form>::String, ty: Option<<MetaForm as Form>::Type>) -> Self {
213 Self { name, ty }
214 }
215}
216
217impl TypeParameter<PortableForm> {
218 pub fn new_portable(
220 name: <PortableForm as Form>::String,
221 ty: Option<<PortableForm as Form>::Type>,
222 ) -> Self {
223 Self { name, ty }
224 }
225}
226
227impl<T> TypeParameter<T>
228where
229 T: Form,
230{
231 #[deprecated(
235 since = "2.5.0",
236 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
237 )]
238 pub fn ty(&self) -> Option<&T::Type> {
239 self.ty.as_ref()
240 }
241
242 #[deprecated(
244 since = "2.5.0",
245 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
246 )]
247 pub fn name(&self) -> &T::String {
248 &self.name
249 }
250}
251
252#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
264#[cfg_attr(
265 feature = "serde",
266 serde(bound(
267 serialize = "T::Type: Serialize, T::String: Serialize",
268 deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
269 ))
270)]
271#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
272#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
273#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
274#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Encode)]
275pub enum TypeDef<T: Form = MetaForm> {
276 #[codec(index = 0)]
278 Composite(TypeDefComposite<T>),
279 #[codec(index = 1)]
281 Variant(TypeDefVariant<T>),
282 #[codec(index = 2)]
284 Sequence(TypeDefSequence<T>),
285 #[codec(index = 3)]
287 Array(TypeDefArray<T>),
288 #[codec(index = 4)]
290 Tuple(TypeDefTuple<T>),
291 #[codec(index = 5)]
293 Primitive(TypeDefPrimitive),
294 #[codec(index = 6)]
296 Compact(TypeDefCompact<T>),
297 #[codec(index = 7)]
299 BitSequence(TypeDefBitSequence<T>),
300}
301
302macro_rules! impl_from_type_defs {
303 ( $($from:ty => $variant:ident, )* ) => { $(
304 impl<F: Form> From<$from> for TypeDef<F> {
305 fn from(x: $from) -> Self {
306 Self::$variant(x)
307 }
308 }
309 )* }
310}
311
312impl_from_type_defs!(
313 TypeDefComposite<F> => Composite,
314 TypeDefVariant<F> => Variant,
315 TypeDefSequence<F> => Sequence,
316 TypeDefArray<F> => Array,
317 TypeDefTuple<F> => Tuple,
318 TypeDefPrimitive => Primitive,
319 TypeDefCompact<F> => Compact,
320 TypeDefBitSequence<F> => BitSequence,
321);
322
323impl IntoPortable for TypeDef {
324 type Output = TypeDef<PortableForm>;
325
326 fn into_portable(self, registry: &mut Registry) -> Self::Output {
327 match self {
328 TypeDef::Composite(composite) => composite.into_portable(registry).into(),
329 TypeDef::Variant(variant) => variant.into_portable(registry).into(),
330 TypeDef::Sequence(sequence) => sequence.into_portable(registry).into(),
331 TypeDef::Array(array) => array.into_portable(registry).into(),
332 TypeDef::Tuple(tuple) => tuple.into_portable(registry).into(),
333 TypeDef::Primitive(primitive) => primitive.into(),
334 TypeDef::Compact(compact) => compact.into_portable(registry).into(),
335 TypeDef::BitSequence(bitseq) => bitseq.into_portable(registry).into(),
336 }
337 }
338}
339
340#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
346#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
347#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
348#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
349#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
350pub enum TypeDefPrimitive {
351 #[codec(index = 0)]
353 Bool,
354 #[codec(index = 1)]
356 Char,
357 #[codec(index = 2)]
359 Str,
360 #[codec(index = 3)]
362 U8,
363 #[codec(index = 4)]
365 U16,
366 #[codec(index = 5)]
368 U32,
369 #[codec(index = 6)]
371 U64,
372 #[codec(index = 7)]
374 U128,
375 #[codec(index = 8)]
377 U256,
378 #[codec(index = 9)]
380 I8,
381 #[codec(index = 10)]
383 I16,
384 #[codec(index = 11)]
386 I32,
387 #[codec(index = 12)]
389 I64,
390 #[codec(index = 13)]
392 I128,
393 #[codec(index = 14)]
395 I256,
396}
397
398#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
400#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
401#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
402#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
403pub struct TypeDefArray<T: Form = MetaForm> {
404 pub len: u32,
406 #[cfg_attr(feature = "serde", serde(rename = "type"))]
408 pub type_param: T::Type,
409}
410
411impl IntoPortable for TypeDefArray {
412 type Output = TypeDefArray<PortableForm>;
413
414 fn into_portable(self, registry: &mut Registry) -> Self::Output {
415 TypeDefArray {
416 len: self.len,
417 type_param: registry.register_type(&self.type_param),
418 }
419 }
420}
421
422#[allow(clippy::len_without_is_empty)]
423impl<T> TypeDefArray<T>
424where
425 T: Form,
426{
427 pub fn new(len: u32, type_param: <T as Form>::Type) -> Self {
429 Self { len, type_param }
430 }
431
432 #[deprecated(
434 since = "2.5.0",
435 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
436 )]
437 pub fn len(&self) -> u32 {
438 self.len
439 }
440
441 #[deprecated(
443 since = "2.5.0",
444 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
445 )]
446 pub fn type_param(&self) -> &T::Type {
447 &self.type_param
448 }
449}
450
451#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
453#[cfg_attr(
454 feature = "serde",
455 serde(bound(
456 serialize = "T::Type: Serialize, T::String: Serialize",
457 deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
458 ))
459)]
460#[cfg_attr(feature = "serde", serde(transparent))]
461#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
462#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
463#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
464pub struct TypeDefTuple<T: Form = MetaForm> {
465 pub fields: Vec<T::Type>,
467}
468
469impl IntoPortable for TypeDefTuple {
470 type Output = TypeDefTuple<PortableForm>;
471
472 fn into_portable(self, registry: &mut Registry) -> Self::Output {
473 TypeDefTuple {
474 fields: registry.register_types(self.fields),
475 }
476 }
477}
478
479impl TypeDefTuple {
480 pub fn new<T>(type_params: T) -> Self
482 where
483 T: IntoIterator<Item = MetaType>,
484 {
485 Self {
486 fields: type_params
487 .into_iter()
488 .filter(|ty| !ty.is_phantom())
489 .collect(),
490 }
491 }
492
493 pub fn unit() -> Self {
495 Self::new(vec![])
496 }
497}
498
499impl TypeDefTuple<PortableForm> {
500 pub fn new_portable<I>(type_params: I) -> Self
502 where
503 I: IntoIterator<Item = <PortableForm as Form>::Type>,
504 {
505 Self {
506 fields: type_params.into_iter().collect(),
507 }
508 }
509}
510
511impl<T> TypeDefTuple<T>
512where
513 T: Form,
514{
515 #[deprecated(
517 since = "2.5.0",
518 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
519 )]
520 pub fn fields(&self) -> &[T::Type] {
521 &self.fields
522 }
523}
524
525#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
527#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
528#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
529#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
530pub struct TypeDefSequence<T: Form = MetaForm> {
531 #[cfg_attr(feature = "serde", serde(rename = "type"))]
533 pub type_param: T::Type,
534}
535
536impl IntoPortable for TypeDefSequence {
537 type Output = TypeDefSequence<PortableForm>;
538
539 fn into_portable(self, registry: &mut Registry) -> Self::Output {
540 TypeDefSequence {
541 type_param: registry.register_type(&self.type_param),
542 }
543 }
544}
545
546impl TypeDefSequence {
547 pub fn of<T>() -> Self
552 where
553 T: TypeInfo + 'static,
554 {
555 Self::new(MetaType::new::<T>())
556 }
557}
558
559impl<T> TypeDefSequence<T>
560where
561 T: Form,
562{
563 pub fn new(type_param: <T as Form>::Type) -> Self {
567 Self { type_param }
568 }
569
570 #[deprecated(
572 since = "2.5.0",
573 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
574 )]
575 pub fn type_param(&self) -> &T::Type {
576 &self.type_param
577 }
578}
579
580#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
582#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
583#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
584#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
585pub struct TypeDefCompact<T: Form = MetaForm> {
586 #[cfg_attr(feature = "serde", serde(rename = "type"))]
588 pub type_param: T::Type,
589}
590
591impl IntoPortable for TypeDefCompact {
592 type Output = TypeDefCompact<PortableForm>;
593
594 fn into_portable(self, registry: &mut Registry) -> Self::Output {
595 TypeDefCompact {
596 type_param: registry.register_type(&self.type_param),
597 }
598 }
599}
600
601impl<T> TypeDefCompact<T>
602where
603 T: Form,
604{
605 pub fn new(type_param: <T as Form>::Type) -> Self {
607 Self { type_param }
608 }
609
610 #[deprecated(
612 since = "2.5.0",
613 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
614 )]
615 pub fn type_param(&self) -> &T::Type {
616 &self.type_param
617 }
618}
619
620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
627#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
628#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
629#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
630pub struct TypeDefBitSequence<T: Form = MetaForm> {
631 pub bit_store_type: T::Type,
633 pub bit_order_type: T::Type,
635}
636
637impl IntoPortable for TypeDefBitSequence {
638 type Output = TypeDefBitSequence<PortableForm>;
639
640 fn into_portable(self, registry: &mut Registry) -> Self::Output {
641 TypeDefBitSequence {
642 bit_store_type: registry.register_type(&self.bit_store_type),
643 bit_order_type: registry.register_type(&self.bit_order_type),
644 }
645 }
646}
647
648impl<T> TypeDefBitSequence<T>
649where
650 T: Form,
651{
652 #[deprecated(
654 since = "2.5.0",
655 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
656 )]
657 pub fn bit_order_type(&self) -> &T::Type {
658 &self.bit_order_type
659 }
660
661 #[deprecated(
663 since = "2.5.0",
664 note = "Prefer to access the fields directly; this getter will be removed in the next major version"
665 )]
666 pub fn bit_store_type(&self) -> &T::Type {
667 &self.bit_store_type
668 }
669}
670
671impl TypeDefBitSequence {
672 pub fn new<Store, Order>() -> Self
679 where
680 Store: TypeInfo + 'static,
681 Order: TypeInfo + 'static,
682 {
683 Self {
684 bit_store_type: MetaType::new::<Store>(),
685 bit_order_type: MetaType::new::<Order>(),
686 }
687 }
688}
689
690impl TypeDefBitSequence<PortableForm> {
691 pub fn new_portable(
693 bit_store_type: <PortableForm as Form>::Type,
694 bit_order_type: <PortableForm as Form>::Type,
695 ) -> Self {
696 Self {
697 bit_store_type,
698 bit_order_type,
699 }
700 }
701}