frame_metadata/
v16.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#[cfg(feature = "decode")]
17use codec::Decode;
18#[cfg(feature = "serde_full")]
19use serde::Serialize;
20
21use super::{RuntimeMetadataPrefixed, META_RESERVED};
22use codec::{Compact, Encode};
23use scale_info::{
24	form::{Form, MetaForm, PortableForm},
25	prelude::{collections::BTreeMap, vec::Vec},
26	IntoPortable, PortableRegistry, Registry,
27};
28
29// These types have not changed, so we re-export from our v14/v15 definitions:
30pub use super::v14::{StorageEntryModifier, StorageEntryType, StorageHasher};
31pub use super::v15::{CustomMetadata, CustomValueMetadata, OuterEnums};
32
33/// The metadata for a method or function parameter. This is identical to
34/// [`crate::v15::RuntimeApiMethodParamMetadata`].
35pub type FunctionParamMetadata<T> = super::v15::RuntimeApiMethodParamMetadata<T>;
36
37/// Latest runtime metadata.
38pub type RuntimeMetadataLastVersion = RuntimeMetadataV16;
39
40impl From<RuntimeMetadataLastVersion> for super::RuntimeMetadataPrefixed {
41	fn from(metadata: RuntimeMetadataLastVersion) -> RuntimeMetadataPrefixed {
42		RuntimeMetadataPrefixed(META_RESERVED, super::RuntimeMetadata::V16(metadata))
43	}
44}
45
46/// The metadata of a runtime.
47#[derive(Clone, PartialEq, Eq, Encode, Debug)]
48#[cfg_attr(feature = "decode", derive(Decode))]
49#[cfg_attr(feature = "serde_full", derive(Serialize))]
50pub struct RuntimeMetadataV16 {
51	/// Type registry containing all types used in the metadata.
52	pub types: PortableRegistry,
53	/// Metadata of all the pallets.
54	pub pallets: Vec<PalletMetadata<PortableForm>>,
55	/// Metadata of the extrinsic.
56	pub extrinsic: ExtrinsicMetadata<PortableForm>,
57	/// Metadata of the Runtime API.
58	pub apis: Vec<RuntimeApiMetadata<PortableForm>>,
59	/// The outer enums types as found in the runtime.
60	pub outer_enums: OuterEnums<PortableForm>,
61	/// Allows users to add custom types to the metadata.
62	pub custom: CustomMetadata<PortableForm>,
63}
64
65impl RuntimeMetadataV16 {
66	/// Create a new instance of [`RuntimeMetadataV16`].
67	pub fn new(
68		pallets: Vec<PalletMetadata>,
69		extrinsic: ExtrinsicMetadata,
70		apis: Vec<RuntimeApiMetadata>,
71		outer_enums: OuterEnums,
72		custom: CustomMetadata,
73	) -> Self {
74		let mut registry = Registry::new();
75		// extrinsic types need to be collected first to ensure CheckMetadataHash hash
76		// is stable across different metadata versions
77		let extrinsic = extrinsic.into_portable(&mut registry);
78		let pallets = registry.map_into_portable(pallets);
79		let apis = registry.map_into_portable(apis);
80		let outer_enums = outer_enums.into_portable(&mut registry);
81		let custom = custom.into_portable(&mut registry);
82
83		Self {
84			types: registry.into(),
85			pallets,
86			extrinsic,
87			apis,
88			outer_enums,
89			custom,
90		}
91	}
92}
93
94/// Metadata of a runtime trait.
95#[derive(Clone, PartialEq, Eq, Encode, Debug)]
96#[cfg_attr(feature = "decode", derive(Decode))]
97#[cfg_attr(feature = "serde_full", derive(Serialize))]
98#[cfg_attr(
99	feature = "serde_full",
100	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
101)]
102pub struct RuntimeApiMetadata<T: Form = MetaForm> {
103	/// Trait name.
104	pub name: T::String,
105	/// Trait methods.
106	pub methods: Vec<RuntimeApiMethodMetadata<T>>,
107	/// Trait documentation.
108	pub docs: Vec<T::String>,
109	/// Runtime API version.
110	pub version: Compact<u32>,
111	/// Deprecation info.
112	pub deprecation_info: ItemDeprecationInfo<T>,
113}
114
115impl IntoPortable for RuntimeApiMetadata {
116	type Output = RuntimeApiMetadata<PortableForm>;
117
118	fn into_portable(self, registry: &mut Registry) -> Self::Output {
119		RuntimeApiMetadata {
120			name: self.name.into_portable(registry),
121			methods: registry.map_into_portable(self.methods),
122			docs: registry.map_into_portable(self.docs),
123			version: self.version,
124			deprecation_info: self.deprecation_info.into_portable(registry),
125		}
126	}
127}
128
129/// Metadata of a runtime method.
130#[derive(Clone, PartialEq, Eq, Encode, Debug)]
131#[cfg_attr(feature = "decode", derive(Decode))]
132#[cfg_attr(feature = "serde_full", derive(Serialize))]
133#[cfg_attr(
134	feature = "serde_full",
135	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
136)]
137pub struct RuntimeApiMethodMetadata<T: Form = MetaForm> {
138	/// Method name.
139	pub name: T::String,
140	/// Method parameters.
141	pub inputs: Vec<FunctionParamMetadata<T>>,
142	/// Method output.
143	pub output: T::Type,
144	/// Method documentation.
145	pub docs: Vec<T::String>,
146	/// Deprecation info
147	pub deprecation_info: ItemDeprecationInfo<T>,
148}
149
150impl IntoPortable for RuntimeApiMethodMetadata {
151	type Output = RuntimeApiMethodMetadata<PortableForm>;
152
153	fn into_portable(self, registry: &mut Registry) -> Self::Output {
154		RuntimeApiMethodMetadata {
155			name: self.name.into_portable(registry),
156			inputs: registry.map_into_portable(self.inputs),
157			output: registry.register_type(&self.output),
158			docs: registry.map_into_portable(self.docs),
159			deprecation_info: self.deprecation_info.into_portable(registry),
160		}
161	}
162}
163
164/// Metadata of the extrinsic used by the runtime.
165#[derive(Clone, PartialEq, Eq, Encode, Debug)]
166#[cfg_attr(feature = "decode", derive(Decode))]
167#[cfg_attr(feature = "serde_full", derive(Serialize))]
168#[cfg_attr(
169	feature = "serde_full",
170	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
171)]
172pub struct ExtrinsicMetadata<T: Form = MetaForm> {
173	/// Extrinsic versions supported by the runtime.
174	pub versions: Vec<u8>,
175	/// The type of the address that signs the extrinsic
176	pub address_ty: T::Type,
177	/// The type of the outermost Call enum.
178	// Dev note: this is also exposed in outer_enums, but we duplicate
179	// it here so that ExtrinsicMetadata, on its own, provides everything
180	// needed to decode an extrinsic.
181	pub call_ty: T::Type,
182	/// The type of the extrinsic's signature.
183	pub signature_ty: T::Type,
184	/// A mapping of supported transaction extrinsic versions to their respective transaction extension indexes.
185	///
186	/// For each supported version number, list the indexes, in order, of the extensions used.
187	pub transaction_extensions_by_version: BTreeMap<u8, Vec<Compact<u32>>>,
188	/// The transaction extensions in the order they appear in the extrinsic.
189	pub transaction_extensions: Vec<TransactionExtensionMetadata<T>>,
190}
191
192impl IntoPortable for ExtrinsicMetadata {
193	type Output = ExtrinsicMetadata<PortableForm>;
194
195	fn into_portable(self, registry: &mut Registry) -> Self::Output {
196		// the collection order needs to be stable across different metadata versions
197		// to ensure CheckMetadataHash hash is invariant
198		ExtrinsicMetadata {
199			versions: self.versions,
200			address_ty: registry.register_type(&self.address_ty),
201			call_ty: registry.register_type(&self.call_ty),
202			signature_ty: registry.register_type(&self.signature_ty),
203			transaction_extensions_by_version: self.transaction_extensions_by_version,
204			transaction_extensions: registry.map_into_portable(self.transaction_extensions),
205		}
206	}
207}
208
209/// Metadata of an extrinsic's transaction extension.
210#[derive(Clone, PartialEq, Eq, Encode, Debug)]
211#[cfg_attr(feature = "decode", derive(Decode))]
212#[cfg_attr(feature = "serde_full", derive(Serialize))]
213#[cfg_attr(
214	feature = "serde_full",
215	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
216)]
217pub struct TransactionExtensionMetadata<T: Form = MetaForm> {
218	/// The unique transaction extension identifier, which may be different from the type name.
219	pub identifier: T::String,
220	/// The type of the transaction extension, with the data to be included in the extrinsic.
221	pub ty: T::Type,
222	/// The type of the implicit data, with the data to be included in the signed payload.
223	pub implicit: T::Type,
224}
225
226impl IntoPortable for TransactionExtensionMetadata {
227	type Output = TransactionExtensionMetadata<PortableForm>;
228
229	fn into_portable(self, registry: &mut Registry) -> Self::Output {
230		TransactionExtensionMetadata {
231			identifier: self.identifier.into_portable(registry),
232			ty: registry.register_type(&self.ty),
233			implicit: registry.register_type(&self.implicit),
234		}
235	}
236}
237
238/// All metadata about an runtime pallet.
239#[derive(Clone, PartialEq, Eq, Encode, Debug)]
240#[cfg_attr(feature = "decode", derive(Decode))]
241#[cfg_attr(feature = "serde_full", derive(Serialize))]
242#[cfg_attr(
243	feature = "serde_full",
244	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
245)]
246pub struct PalletMetadata<T: Form = MetaForm> {
247	/// Pallet name.
248	pub name: T::String,
249	/// Pallet storage metadata.
250	pub storage: Option<PalletStorageMetadata<T>>,
251	/// Pallet calls metadata.
252	pub calls: Option<PalletCallMetadata<T>>,
253	/// Pallet event metadata.
254	pub event: Option<PalletEventMetadata<T>>,
255	/// Pallet constants metadata.
256	pub constants: Vec<PalletConstantMetadata<T>>,
257	/// Pallet error metadata.
258	pub error: Option<PalletErrorMetadata<T>>,
259	/// Config's trait associated types.
260	pub associated_types: Vec<PalletAssociatedTypeMetadata<T>>,
261	/// Pallet view functions metadata.
262	pub view_functions: Vec<PalletViewFunctionMetadata<T>>,
263	/// Define the index of the pallet, this index will be used for the encoding of pallet event,
264	/// call and origin variants.
265	pub index: u8,
266	/// Pallet documentation.
267	pub docs: Vec<T::String>,
268	/// Deprecation info
269	pub deprecation_info: ItemDeprecationInfo<T>,
270}
271
272impl IntoPortable for PalletMetadata {
273	type Output = PalletMetadata<PortableForm>;
274
275	fn into_portable(self, registry: &mut Registry) -> Self::Output {
276		PalletMetadata {
277			name: self.name.into_portable(registry),
278			storage: self.storage.map(|storage| storage.into_portable(registry)),
279			calls: self.calls.map(|calls| calls.into_portable(registry)),
280			event: self.event.map(|event| event.into_portable(registry)),
281			constants: registry.map_into_portable(self.constants),
282			error: self.error.map(|error| error.into_portable(registry)),
283			associated_types: registry.map_into_portable(self.associated_types),
284			view_functions: registry.map_into_portable(self.view_functions),
285			index: self.index,
286			docs: registry.map_into_portable(self.docs),
287			deprecation_info: self.deprecation_info.into_portable(registry),
288		}
289	}
290}
291
292/// Metadata for all calls in a pallet.
293#[derive(Clone, PartialEq, Eq, Encode, Debug)]
294#[cfg_attr(feature = "decode", derive(Decode))]
295#[cfg_attr(feature = "serde_full", derive(Serialize))]
296#[cfg_attr(
297	feature = "serde_full",
298	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
299)]
300pub struct PalletCallMetadata<T: Form = MetaForm> {
301	/// The corresponding enum type for the pallet call.
302	pub ty: T::Type,
303	/// Deprecation status of the pallet call
304	pub deprecation_info: EnumDeprecationInfo<T>,
305}
306
307impl IntoPortable for PalletCallMetadata {
308	type Output = PalletCallMetadata<PortableForm>;
309
310	fn into_portable(self, registry: &mut Registry) -> Self::Output {
311		PalletCallMetadata {
312			ty: registry.register_type(&self.ty),
313			deprecation_info: self.deprecation_info.into_portable(registry),
314		}
315	}
316}
317
318/// All metadata of the pallet's storage.
319#[derive(Clone, PartialEq, Eq, Encode, Debug)]
320#[cfg_attr(feature = "decode", derive(Decode))]
321#[cfg_attr(feature = "serde_full", derive(Serialize))]
322#[cfg_attr(
323	feature = "serde_full",
324	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
325)]
326pub struct PalletStorageMetadata<T: Form = MetaForm> {
327	/// The common prefix used by all storage entries.
328	pub prefix: T::String,
329	/// Metadata for all storage entries.
330	pub entries: Vec<StorageEntryMetadata<T>>,
331}
332
333impl IntoPortable for PalletStorageMetadata {
334	type Output = PalletStorageMetadata<PortableForm>;
335
336	fn into_portable(self, registry: &mut Registry) -> Self::Output {
337		PalletStorageMetadata {
338			prefix: self.prefix.into_portable(registry),
339			entries: registry.map_into_portable(self.entries),
340		}
341	}
342}
343
344/// Metadata about one storage entry.
345#[derive(Clone, PartialEq, Eq, Encode, Debug)]
346#[cfg_attr(feature = "decode", derive(Decode))]
347#[cfg_attr(feature = "serde_full", derive(Serialize))]
348#[cfg_attr(
349	feature = "serde_full",
350	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
351)]
352pub struct StorageEntryMetadata<T: Form = MetaForm> {
353	/// Variable name of the storage entry.
354	pub name: T::String,
355	/// An `Option` modifier of that storage entry.
356	pub modifier: StorageEntryModifier,
357	/// Type of the value stored in the entry.
358	pub ty: StorageEntryType<T>,
359	/// Default value (SCALE encoded).
360	pub default: Vec<u8>,
361	/// Storage entry documentation.
362	pub docs: Vec<T::String>,
363	/// Deprecation info
364	pub deprecation_info: ItemDeprecationInfo<T>,
365}
366
367impl IntoPortable for StorageEntryMetadata {
368	type Output = StorageEntryMetadata<PortableForm>;
369
370	fn into_portable(self, registry: &mut Registry) -> Self::Output {
371		StorageEntryMetadata {
372			name: self.name.into_portable(registry),
373			modifier: self.modifier,
374			ty: self.ty.into_portable(registry),
375			default: self.default,
376			docs: registry.map_into_portable(self.docs),
377			deprecation_info: self.deprecation_info.into_portable(registry),
378		}
379	}
380}
381
382/// Metadata about the pallet Event type.
383#[derive(Clone, PartialEq, Eq, Encode, Debug)]
384#[cfg_attr(feature = "decode", derive(Decode))]
385#[cfg_attr(feature = "serde_full", derive(Serialize))]
386#[cfg_attr(
387	feature = "serde_full",
388	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
389)]
390pub struct PalletEventMetadata<T: Form = MetaForm> {
391	/// The Event type.
392	pub ty: T::Type,
393	/// Deprecation info
394	pub deprecation_info: EnumDeprecationInfo<T>,
395}
396
397impl IntoPortable for PalletEventMetadata {
398	type Output = PalletEventMetadata<PortableForm>;
399
400	fn into_portable(self, registry: &mut Registry) -> Self::Output {
401		PalletEventMetadata {
402			ty: registry.register_type(&self.ty),
403			deprecation_info: self.deprecation_info.into_portable(registry),
404		}
405	}
406}
407
408/// Metadata about one pallet constant.
409#[derive(Clone, PartialEq, Eq, Encode, Debug)]
410#[cfg_attr(feature = "decode", derive(Decode))]
411#[cfg_attr(feature = "serde_full", derive(Serialize))]
412#[cfg_attr(
413	feature = "serde_full",
414	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
415)]
416pub struct PalletConstantMetadata<T: Form = MetaForm> {
417	/// Name of the pallet constant.
418	pub name: T::String,
419	/// Type of the pallet constant.
420	pub ty: T::Type,
421	/// Value stored in the constant (SCALE encoded).
422	pub value: Vec<u8>,
423	/// Documentation of the constant.
424	pub docs: Vec<T::String>,
425	/// Deprecation info
426	pub deprecation_info: ItemDeprecationInfo<T>,
427}
428
429impl IntoPortable for PalletConstantMetadata {
430	type Output = PalletConstantMetadata<PortableForm>;
431
432	fn into_portable(self, registry: &mut Registry) -> Self::Output {
433		PalletConstantMetadata {
434			name: self.name.into_portable(registry),
435			ty: registry.register_type(&self.ty),
436			value: self.value,
437			docs: registry.map_into_portable(self.docs),
438			deprecation_info: self.deprecation_info.into_portable(registry),
439		}
440	}
441}
442
443/// Metadata about a pallet error.
444#[derive(Clone, PartialEq, Eq, Encode, Debug)]
445#[cfg_attr(feature = "decode", derive(Decode))]
446#[cfg_attr(feature = "serde_full", derive(Serialize))]
447#[cfg_attr(
448	feature = "serde_full",
449	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
450)]
451pub struct PalletErrorMetadata<T: Form = MetaForm> {
452	/// The error type information.
453	pub ty: T::Type,
454	/// Deprecation info
455	pub deprecation_info: EnumDeprecationInfo<T>,
456}
457
458impl IntoPortable for PalletErrorMetadata {
459	type Output = PalletErrorMetadata<PortableForm>;
460
461	fn into_portable(self, registry: &mut Registry) -> Self::Output {
462		PalletErrorMetadata {
463			ty: registry.register_type(&self.ty),
464			deprecation_info: self.deprecation_info.into_portable(registry),
465		}
466	}
467}
468
469/// Metadata of a pallet's associated type.
470#[derive(Clone, PartialEq, Eq, Encode, Debug)]
471#[cfg_attr(feature = "decode", derive(Decode))]
472#[cfg_attr(feature = "serde_full", derive(Serialize))]
473#[cfg_attr(
474	feature = "serde_full",
475	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
476)]
477pub struct PalletAssociatedTypeMetadata<T: Form = MetaForm> {
478	/// The name of the associated type.
479	pub name: T::String,
480	/// The type of the associated type.
481	pub ty: T::Type,
482	/// The documentation of the associated type.
483	pub docs: Vec<T::String>,
484}
485
486impl IntoPortable for PalletAssociatedTypeMetadata {
487	type Output = PalletAssociatedTypeMetadata<PortableForm>;
488
489	fn into_portable(self, registry: &mut Registry) -> Self::Output {
490		PalletAssociatedTypeMetadata {
491			name: self.name.into_portable(registry),
492			ty: registry.register_type(&self.ty),
493			docs: registry.map_into_portable(self.docs),
494		}
495	}
496}
497
498/// Metadata about a pallet view function.
499#[derive(Clone, PartialEq, Eq, Encode, Debug)]
500#[cfg_attr(feature = "decode", derive(Decode))]
501#[cfg_attr(feature = "serde_full", derive(Serialize))]
502#[cfg_attr(
503	feature = "serde_full",
504	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
505)]
506pub struct PalletViewFunctionMetadata<T: Form = MetaForm> {
507	/// Method id.
508	pub id: [u8; 32],
509	/// Method name.
510	pub name: T::String,
511	/// Method parameters.
512	pub inputs: Vec<FunctionParamMetadata<T>>,
513	/// Method output.
514	pub output: T::Type,
515	/// Method documentation.
516	pub docs: Vec<T::String>,
517	/// Deprecation info
518	pub deprecation_info: ItemDeprecationInfo<T>,
519}
520
521impl IntoPortable for PalletViewFunctionMetadata {
522	type Output = PalletViewFunctionMetadata<PortableForm>;
523
524	fn into_portable(self, registry: &mut Registry) -> Self::Output {
525		PalletViewFunctionMetadata {
526			id: self.id,
527			name: self.name.into_portable(registry),
528			inputs: registry.map_into_portable(self.inputs),
529			output: registry.register_type(&self.output),
530			docs: registry.map_into_portable(self.docs),
531			deprecation_info: self.deprecation_info.into_portable(registry),
532		}
533	}
534}
535
536/// Deprecation information for generic items.
537#[derive(Clone, PartialEq, Eq, Encode, Debug)]
538#[cfg_attr(feature = "decode", derive(Decode))]
539#[cfg_attr(feature = "serde_full", derive(Serialize))]
540#[cfg_attr(
541	feature = "serde_full",
542	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
543)]
544pub enum ItemDeprecationInfo<T: Form = MetaForm> {
545	/// Item is not deprecated.
546	NotDeprecated,
547	/// Item is fully deprecated without a note.
548	DeprecatedWithoutNote,
549	/// Item is fully deprecated with a note and an optional `since` field.
550	Deprecated {
551		/// Note explaining the deprecation
552		note: T::String,
553		/// Optional value for noting the version when the deprecation occurred.
554		since: Option<T::String>,
555	},
556}
557
558impl IntoPortable for ItemDeprecationInfo {
559	type Output = ItemDeprecationInfo<PortableForm>;
560
561	fn into_portable(self, registry: &mut Registry) -> Self::Output {
562		match self {
563			Self::NotDeprecated => ItemDeprecationInfo::NotDeprecated,
564			Self::DeprecatedWithoutNote => ItemDeprecationInfo::DeprecatedWithoutNote,
565			Self::Deprecated { note, since } => {
566				let note = note.into_portable(registry);
567				let since = since.map(|x| x.into_portable(registry));
568				ItemDeprecationInfo::Deprecated { note, since }
569			}
570		}
571	}
572}
573
574/// Deprecation information for enums in which specific variants can be deprecated.
575/// If the map is empty, then nothing is deprecated.
576#[derive(Clone, PartialEq, Eq, Encode, Debug)]
577#[cfg_attr(feature = "decode", derive(Decode))]
578#[cfg_attr(feature = "serde_full", derive(Serialize))]
579#[cfg_attr(
580	feature = "serde_full",
581	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
582)]
583pub struct EnumDeprecationInfo<T: Form = MetaForm>(pub BTreeMap<u8, VariantDeprecationInfo<T>>);
584
585impl<T: Form> EnumDeprecationInfo<T> {
586	/// Construct an instance in which nothing is marked for deprecation.
587	pub fn nothing_deprecated() -> Self {
588		Self(BTreeMap::new())
589	}
590
591	/// Are any variants deprecated?
592	pub fn has_deprecated_variants(&self) -> bool {
593		!self.0.is_empty()
594	}
595
596	/// Is a specific variant deprecated?
597	pub fn is_variant_deprecated(&self, variant_index: u8) -> bool {
598		self.0.contains_key(&variant_index)
599	}
600}
601
602impl IntoPortable for EnumDeprecationInfo {
603	type Output = EnumDeprecationInfo<PortableForm>;
604
605	fn into_portable(self, registry: &mut Registry) -> Self::Output {
606		let entries = self
607			.0
608			.into_iter()
609			.map(|(k, entry)| (k, entry.into_portable(registry)));
610		EnumDeprecationInfo(entries.collect())
611	}
612}
613
614/// Deprecation information for an item or variant in the metadata.
615// Dev note: we use #[codec(index)] here to align the indexes with those
616// of ItemDeprecationInfo, allowing both can decode into this asa convenience.
617#[derive(Clone, PartialEq, Eq, Encode, Debug)]
618#[cfg_attr(feature = "decode", derive(Decode))]
619#[cfg_attr(feature = "serde_full", derive(Serialize))]
620#[cfg_attr(
621	feature = "serde_full",
622	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
623)]
624pub enum VariantDeprecationInfo<T: Form = MetaForm> {
625	/// Variant is deprecated without a note.
626	#[codec(index = 1)]
627	DeprecatedWithoutNote,
628	/// Variant is deprecated with a note and an optional `since` field.
629	#[codec(index = 2)]
630	Deprecated {
631		/// Note explaining the deprecation
632		note: T::String,
633		/// Optional value for noting the version when the deprecation occurred.
634		since: Option<T::String>,
635	},
636}
637
638impl IntoPortable for VariantDeprecationInfo {
639	type Output = VariantDeprecationInfo<PortableForm>;
640
641	fn into_portable(self, registry: &mut Registry) -> Self::Output {
642		match self {
643			Self::Deprecated { note, since } => {
644				let note = note.into_portable(registry);
645				let since = since.map(|x| x.into_portable(registry));
646				VariantDeprecationInfo::Deprecated { note, since }
647			}
648			Self::DeprecatedWithoutNote => VariantDeprecationInfo::DeprecatedWithoutNote,
649		}
650	}
651}