1use crate::prelude::{
16 borrow::{Cow, ToOwned},
17 boxed::Box,
18 collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque},
19 fmt,
20 marker::PhantomData,
21 ops::{Range, RangeInclusive},
22 rc::Rc,
23 string::String,
24 sync::Arc,
25 time::Duration,
26 vec::Vec,
27};
28
29use crate::{
30 build::*, MetaType, Path, Type, TypeDefArray, TypeDefCompact, TypeDefPrimitive,
31 TypeDefSequence, TypeDefTuple, TypeInfo,
32};
33use core::num::{
34 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
35 NonZeroU32, NonZeroU64, NonZeroU8,
36};
37
38macro_rules! impl_metadata_for_primitives {
39 ( $( $t:ty => $ident_kind:expr, )* ) => { $(
40 impl TypeInfo for $t {
41 type Identity = Self;
42
43 fn type_info() -> Type {
44 $ident_kind.into()
45 }
46 }
47 )* }
48}
49
50impl_metadata_for_primitives!(
51 bool => TypeDefPrimitive::Bool,
52 char => TypeDefPrimitive::Char,
53 u8 => TypeDefPrimitive::U8,
54 u16 => TypeDefPrimitive::U16,
55 u32 => TypeDefPrimitive::U32,
56 u64 => TypeDefPrimitive::U64,
57 u128 => TypeDefPrimitive::U128,
58 i8 => TypeDefPrimitive::I8,
59 i16 => TypeDefPrimitive::I16,
60 i32 => TypeDefPrimitive::I32,
61 i64 => TypeDefPrimitive::I64,
62 i128 => TypeDefPrimitive::I128,
63);
64
65impl<T: TypeInfo + 'static, const N: usize> TypeInfo for [T; N] {
66 type Identity = Self;
67
68 fn type_info() -> Type {
69 TypeDefArray::new(N as u32, MetaType::new::<T>()).into()
70 }
71}
72
73macro_rules! impl_metadata_for_tuple {
74 ( $($ty:ident),* ) => {
75 impl<$($ty),*> TypeInfo for ($($ty,)*)
76 where
77 $(
78 $ty: TypeInfo+ 'static,
79 )*
80 {
81 type Identity = Self;
82
83 fn type_info() -> Type {
84 TypeDefTuple::new(tuple_meta_type!($($ty),*)).into()
85 }
86 }
87 }
88}
89
90impl_metadata_for_tuple!();
91impl_metadata_for_tuple!(A);
92impl_metadata_for_tuple!(A, B);
93impl_metadata_for_tuple!(A, B, C);
94impl_metadata_for_tuple!(A, B, C, D);
95impl_metadata_for_tuple!(A, B, C, D, E);
96impl_metadata_for_tuple!(A, B, C, D, E, F);
97impl_metadata_for_tuple!(A, B, C, D, E, F, G);
98impl_metadata_for_tuple!(A, B, C, D, E, F, G, H);
99impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I);
100impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J);
101impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K);
102impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
103impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M);
104impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
105impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
106impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
107impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
108impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
109impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
110impl_metadata_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
111
112macro_rules! impl_for_non_zero {
113 ( $( $t: ty: $inner: ty ),* $(,)? ) => {
114 $(
115 impl TypeInfo for $t {
116 type Identity = Self;
117 fn type_info() -> Type {
118 Type::builder()
119 .path(Path::prelude(stringify!($t)))
120 .composite(Fields::unnamed().field(|f| f.ty::<$inner>()))
121 }
122 }
123 )*
124 };
125}
126
127impl_for_non_zero!(
128 NonZeroI8: i8,
129 NonZeroI16: i16,
130 NonZeroI32: i32,
131 NonZeroI64: i64,
132 NonZeroI128: i128,
133 NonZeroU8: u8,
134 NonZeroU16: u16,
135 NonZeroU32: u32,
136 NonZeroU64: u64,
137 NonZeroU128: u128
138);
139
140impl TypeInfo for Duration {
141 type Identity = Self;
142
143 fn type_info() -> Type {
144 Type::builder().path(Path::prelude("Duration")).composite(
145 Fields::unnamed()
146 .field(|f| {
147 f.ty::<u64>().type_name("u64")
149 })
150 .field(|f| {
151 f.ty::<u32>().type_name("u32")
153 }),
154 )
155 }
156}
157
158impl<T> TypeInfo for Vec<T>
159where
160 T: TypeInfo + 'static,
161{
162 type Identity = [T];
163
164 fn type_info() -> Type {
165 Self::Identity::type_info()
166 }
167}
168
169impl<T> TypeInfo for VecDeque<T>
170where
171 T: TypeInfo + 'static,
172{
173 type Identity = [T];
174
175 fn type_info() -> Type {
176 Self::Identity::type_info()
177 }
178}
179
180impl<T> TypeInfo for Option<T>
181where
182 T: TypeInfo + 'static,
183{
184 type Identity = Self;
185
186 fn type_info() -> Type {
187 Type::builder()
188 .path(Path::prelude("Option"))
189 .type_params(type_params![T])
190 .variant(
191 Variants::new()
192 .variant("None", |v| v.index(0))
193 .variant("Some", |v| {
194 v.index(1).fields(Fields::unnamed().field(|f| f.ty::<T>()))
195 }),
196 )
197 }
198}
199
200impl<T, E> TypeInfo for Result<T, E>
201where
202 T: TypeInfo + 'static,
203 E: TypeInfo + 'static,
204{
205 type Identity = Self;
206
207 fn type_info() -> Type {
208 Type::builder()
209 .path(Path::prelude("Result"))
210 .type_params(type_params!(T, E))
211 .variant(
212 Variants::new()
213 .variant("Ok", |v| {
214 v.index(0).fields(Fields::unnamed().field(|f| f.ty::<T>()))
215 })
216 .variant("Err", |v| {
217 v.index(1).fields(Fields::unnamed().field(|f| f.ty::<E>()))
218 }),
219 )
220 }
221}
222
223impl<T> TypeInfo for Cow<'static, T>
224where
225 T: ToOwned + TypeInfo + ?Sized + 'static,
226{
227 type Identity = Self;
228
229 fn type_info() -> Type {
230 Type::builder()
231 .path(Path::prelude("Cow"))
232 .type_params(type_params!(T))
233 .composite(Fields::unnamed().field(|f| f.ty::<T>()))
234 }
235}
236
237impl<K, V> TypeInfo for BTreeMap<K, V>
238where
239 K: TypeInfo + 'static,
240 V: TypeInfo + 'static,
241{
242 type Identity = Self;
243
244 fn type_info() -> Type {
245 Type::builder()
246 .path(Path::prelude("BTreeMap"))
247 .type_params(type_params![K, V])
248 .composite(Fields::unnamed().field(|f| f.ty::<[(K, V)]>()))
249 }
250}
251
252impl<T> TypeInfo for BTreeSet<T>
253where
254 T: TypeInfo + 'static,
255{
256 type Identity = Self;
257
258 fn type_info() -> Type {
259 Type::builder()
260 .path(Path::prelude("BTreeSet"))
261 .type_params(type_params![T])
262 .composite(Fields::unnamed().field(|f| f.ty::<[T]>()))
263 }
264}
265
266impl<T> TypeInfo for BinaryHeap<T>
267where
268 T: TypeInfo + 'static,
269{
270 type Identity = Self;
271
272 fn type_info() -> Type {
273 Type::builder()
274 .path(Path::prelude("BinaryHeap"))
275 .type_params(type_params![T])
276 .composite(Fields::unnamed().field(|f| f.ty::<[T]>()))
277 }
278}
279
280impl<T> TypeInfo for Box<T>
281where
282 T: TypeInfo + ?Sized + 'static,
283{
284 type Identity = T;
285
286 fn type_info() -> Type {
287 Self::Identity::type_info()
288 }
289}
290
291impl<T> TypeInfo for Rc<T>
292where
293 T: TypeInfo + ?Sized + 'static,
294{
295 type Identity = T;
296
297 fn type_info() -> Type {
298 Self::Identity::type_info()
299 }
300}
301
302impl<T> TypeInfo for Arc<T>
303where
304 T: TypeInfo + ?Sized + 'static,
305{
306 type Identity = T;
307
308 fn type_info() -> Type {
309 Self::Identity::type_info()
310 }
311}
312
313impl<T> TypeInfo for &T
314where
315 T: TypeInfo + ?Sized + 'static,
316{
317 type Identity = T;
318
319 fn type_info() -> Type {
320 Self::Identity::type_info()
321 }
322}
323
324impl<T> TypeInfo for &mut T
325where
326 T: TypeInfo + ?Sized + 'static,
327{
328 type Identity = T;
329
330 fn type_info() -> Type {
331 Self::Identity::type_info()
332 }
333}
334
335impl<T> TypeInfo for [T]
336where
337 T: TypeInfo + 'static,
338{
339 type Identity = Self;
340
341 fn type_info() -> Type {
342 TypeDefSequence::of::<T>().into()
343 }
344}
345
346impl TypeInfo for str {
347 type Identity = Self;
348
349 fn type_info() -> Type {
350 TypeDefPrimitive::Str.into()
351 }
352}
353
354impl TypeInfo for String {
355 type Identity = str;
356
357 fn type_info() -> Type {
358 Self::Identity::type_info()
359 }
360}
361
362pub(crate) type PhantomIdentity = PhantomData<()>;
363
364impl<T> TypeInfo for PhantomData<T> {
365 type Identity = PhantomIdentity;
366
367 fn type_info() -> Type {
368 Type::builder()
370 .path(Path::prelude("PhantomData"))
371 .docs(&["PhantomData placeholder, this type should be filtered out"])
372 .composite(Fields::unit())
373 }
374}
375
376impl<T> TypeInfo for scale::Compact<T>
377where
378 T: TypeInfo + 'static,
379{
380 type Identity = Self;
381 fn type_info() -> Type {
382 TypeDefCompact::new(MetaType::new::<T>()).into()
383 }
384}
385
386impl<Idx> TypeInfo for Range<Idx>
387where
388 Idx: TypeInfo + 'static + PartialOrd + fmt::Debug,
389{
390 type Identity = Self;
391 fn type_info() -> Type {
392 Type::builder()
393 .path(Path::prelude("Range"))
394 .type_params(type_params![Idx])
395 .composite(
396 Fields::named()
397 .field(|f| f.name("start").ty::<Idx>().type_name("Idx"))
398 .field(|f| f.name("end").ty::<Idx>().type_name("Idx")),
399 )
400 }
401}
402
403impl<Idx> TypeInfo for RangeInclusive<Idx>
404where
405 Idx: TypeInfo + 'static + PartialOrd + fmt::Debug,
406{
407 type Identity = Self;
408 fn type_info() -> Type {
409 Type::builder()
410 .path(Path::prelude("RangeInclusive"))
411 .type_params(type_params![Idx])
412 .composite(
413 Fields::named()
414 .field(|f| f.name("start").ty::<Idx>().type_name("Idx"))
415 .field(|f| f.name("end").ty::<Idx>().type_name("Idx")),
416 )
417 }
418}
419
420#[cfg(feature = "bit-vec")]
421mod bit_vec {
422 use super::*;
423
424 impl<T, O> TypeInfo for bitvec::vec::BitVec<T, O>
425 where
426 T: bitvec::store::BitStore + TypeInfo + 'static,
427 O: bitvec::order::BitOrder + TypeInfo + 'static,
428 {
429 type Identity = Self;
430
431 fn type_info() -> Type {
432 crate::TypeDefBitSequence::new::<T, O>().into()
433 }
434 }
435
436 impl TypeInfo for bitvec::order::Lsb0 {
437 type Identity = Self;
438
439 fn type_info() -> Type {
440 Type::builder()
441 .path(Path::new("Lsb0", "bitvec::order"))
442 .composite(Fields::unit())
443 }
444 }
445
446 impl TypeInfo for bitvec::order::Msb0 {
447 type Identity = Self;
448
449 fn type_info() -> Type {
450 Type::builder()
451 .path(Path::new("Msb0", "bitvec::order"))
452 .composite(Fields::unit())
453 }
454 }
455}