eosio_scale_info/meta_type.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
15use crate::prelude::{
16 any::TypeId,
17 cmp::Ordering,
18 fmt::{
19 Debug,
20 Error as FmtError,
21 Formatter,
22 },
23 hash::{
24 Hash,
25 Hasher,
26 },
27};
28
29use crate::{
30 form::MetaForm,
31 Type,
32 TypeInfo,
33};
34
35/// A metatype abstraction.
36///
37/// Allows to store compile-time type information at runtime.
38/// This again allows to derive type ID and type definition from it.
39///
40/// This needs a conversion to another representation of types
41/// in order to be serializable.
42#[derive(Clone, Copy)]
43pub struct MetaType {
44 /// Function pointer to get type information.
45 fn_type_info: fn() -> Type<MetaForm>,
46 // The standard type ID (ab)used in order to provide
47 // cheap implementations of the standard traits
48 // such as `PartialEq`, `PartialOrd`, `Debug` and `Hash`.
49 type_id: TypeId,
50}
51
52impl PartialEq for MetaType {
53 fn eq(&self, other: &Self) -> bool {
54 self.type_id == other.type_id
55 }
56}
57
58impl Eq for MetaType {}
59
60impl PartialOrd for MetaType {
61 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
62 self.type_id.partial_cmp(&other.type_id)
63 }
64}
65
66impl Ord for MetaType {
67 fn cmp(&self, other: &Self) -> Ordering {
68 self.type_id.cmp(&other.type_id)
69 }
70}
71
72impl Hash for MetaType {
73 fn hash<H>(&self, state: &mut H)
74 where
75 H: Hasher,
76 {
77 self.type_id.hash(state)
78 }
79}
80
81impl Debug for MetaType {
82 fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
83 self.type_id.fmt(f)
84 }
85}
86
87impl MetaType {
88 /// Creates a new meta type from the given compile-time known type.
89 pub fn new<T>() -> Self
90 where
91 T: TypeInfo + ?Sized + 'static,
92 {
93 Self {
94 fn_type_info: <T as TypeInfo>::type_info,
95 type_id: TypeId::of::<T::Identity>(),
96 }
97 }
98
99 /// Returns the meta type information.
100 pub fn type_info(&self) -> Type<MetaForm> {
101 (self.fn_type_info)()
102 }
103
104 /// Returns the type identifier provided by `core::any`.
105 pub fn type_id(&self) -> TypeId {
106 self.type_id
107 }
108
109 /// Returns true if this represents a type of [`core::marker::PhantomData`].
110 pub(crate) fn is_phantom(&self) -> bool {
111 self == &MetaType::new::<crate::impls::PhantomIdentity>()
112 }
113}