scale_info/
form.rs

1// Copyright 2019-2022 Parity Technologies (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Provides form definitions.
16//!
17//! The forms provided here are used to generically communicate the mode a type
18//! identifier, type definition or structure is using.
19//!
20//! The default form is the `MetaForm`.
21//! It uses `MetaType` for communicating type identifiers and thus acts as
22//! a bridge from runtime to compile time type information.
23//!
24//! The `PortableForm` is a space-efficient representation
25//! that no longer has any connections to the interning registry and thus
26//! can no longer be used to retrieve information from the
27//! original registry. Its sole purpose is for space-efficient serialization.
28//!
29//! Other forms, such as a portable form that is still bound to the registry
30//! (also via lifetime tracking) are possible but current not needed.
31
32use crate::prelude::{any::TypeId, fmt::Debug};
33
34use crate::{interner::UntrackedSymbol, meta_type::MetaType};
35
36#[cfg(feature = "schema")]
37use schemars::JsonSchema;
38#[cfg(feature = "serde")]
39use serde::Serialize;
40
41/// Trait to support derivation of `JsonSchema` for schema generation.
42#[cfg(feature = "schema")]
43pub trait JsonSchemaMaybe: JsonSchema {}
44/// Trait to support derivation of `JsonSchema` for schema generation.
45#[cfg(not(feature = "schema"))]
46pub trait JsonSchemaMaybe {}
47
48/// Trait to control the internal structures of type definitions.
49///
50/// This allows for type-level separation between free forms that can be
51/// instantiated out of the flux and portable forms that require some sort of
52/// interning data structures.
53pub trait Form {
54    /// The type representing the type.
55    type Type: PartialEq + Eq + PartialOrd + Ord + Clone + Debug + JsonSchemaMaybe;
56    /// The string type.
57    type String: AsRef<str> + PartialEq + Eq + PartialOrd + Ord + Clone + Debug + JsonSchemaMaybe;
58}
59
60/// A meta meta-type.
61///
62/// Allows to be converted into other forms such as portable form
63/// through the registry and `IntoPortable`.
64#[cfg_attr(feature = "schema", derive(JsonSchema))]
65#[cfg_attr(feature = "serde", derive(Serialize))]
66#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
67pub enum MetaForm {}
68
69impl Form for MetaForm {
70    type Type = MetaType;
71    type String = &'static str;
72}
73
74/// Portable form that has its lifetime untracked in association to its interner.
75///
76/// # Note
77///
78/// This resolves some lifetime issues with self-referential structs (such as
79/// the registry itself) but can no longer be used to resolve to the original
80/// underlying data.
81#[cfg_attr(feature = "schema", derive(JsonSchema))]
82#[cfg_attr(feature = "serde", derive(Serialize))]
83#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
84pub enum PortableForm {}
85
86cfg_if::cfg_if! {
87    if #[cfg(any(feature = "std", feature = "decode"))] {
88        impl Form for PortableForm {
89            type Type = UntrackedSymbol<TypeId>;
90            // Owned string required for decoding/deserialization
91            type String = crate::prelude::string::String;
92        }
93    } else {
94        impl Form for PortableForm {
95            type Type = UntrackedSymbol<TypeId>;
96            type String = &'static str;
97        }
98    }
99}
100
101// Blanket implementations
102#[cfg(not(feature = "schema"))]
103impl<T> JsonSchemaMaybe for T {}
104#[cfg(feature = "schema")]
105impl<T> JsonSchemaMaybe for T where T: JsonSchema {}