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