1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

            
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// 	http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

            
18
//! Externalities extensions storage.
19
//!
20
//! Externalities support to register a wide variety custom extensions. The [`Extensions`] provides
21
//! some convenience functionality to store and retrieve these extensions.
22
//!
23
//! It is required that each extension implements the [`Extension`] trait.
24

            
25
use crate::Error;
26
use alloc::{
27
	boxed::Box,
28
	collections::btree_map::{BTreeMap, Entry},
29
};
30
use core::{
31
	any::{Any, TypeId},
32
	ops::DerefMut,
33
};
34

            
35
/// Marker trait for types that should be registered as [`Externalities`](crate::Externalities)
36
/// extension.
37
///
38
/// As extensions are stored as `Box<Any>`, this trait should give more confidence that the correct
39
/// type is registered and requested.
40
pub trait Extension: Send + 'static {
41
	/// Return the extension as `&mut dyn Any`.
42
	///
43
	/// This is a trick to make the trait type castable into an `Any`.
44
	fn as_mut_any(&mut self) -> &mut dyn Any;
45

            
46
	/// Get the [`TypeId`] of this `Extension`.
47
	fn type_id(&self) -> TypeId;
48
}
49

            
50
impl Extension for Box<dyn Extension> {
51
	fn as_mut_any(&mut self) -> &mut dyn Any {
52
		(**self).as_mut_any()
53
	}
54

            
55
	fn type_id(&self) -> TypeId {
56
		(**self).type_id()
57
	}
58
}
59

            
60
/// Macro for declaring an extension that usable with [`Extensions`].
61
///
62
/// The extension will be an unit wrapper struct that implements [`Extension`], `Deref` and
63
/// `DerefMut`. The wrapped type is given by the user.
64
///
65
/// # Example
66
/// ```
67
/// # use sp_externalities::decl_extension;
68
/// decl_extension! {
69
///     /// Some test extension
70
///     struct TestExt(String);
71
/// }
72
/// ```
73
#[macro_export]
74
macro_rules! decl_extension {
75
	(
76
		$( #[ $attr:meta ] )*
77
		$vis:vis struct $ext_name:ident ($inner:ty);
78
	) => {
79
		$( #[ $attr ] )*
80
		$vis struct $ext_name (pub $inner);
81

            
82
		impl $crate::Extension for $ext_name {
83
			fn as_mut_any(&mut self) -> &mut dyn core::any::Any {
84
				self
85
			}
86

            
87
			fn type_id(&self) -> core::any::TypeId {
88
				core::any::Any::type_id(self)
89
			}
90
		}
91

            
92
		impl core::ops::Deref for $ext_name {
93
			type Target = $inner;
94

            
95
			fn deref(&self) -> &Self::Target {
96
				&self.0
97
			}
98
		}
99

            
100
		impl core::ops::DerefMut for $ext_name {
101
			fn deref_mut(&mut self) -> &mut Self::Target {
102
				&mut self.0
103
			}
104
		}
105

            
106
		impl From<$inner> for $ext_name {
107
			fn from(inner: $inner) -> Self {
108
				Self(inner)
109
			}
110
 		}
111
	};
112
	(
113
		$( #[ $attr:meta ] )*
114
		$vis:vis struct $ext_name:ident;
115
	) => {
116
		$( #[ $attr ] )*
117
		$vis struct $ext_name;
118

            
119
		impl $crate::Extension for $ext_name {
120
			fn as_mut_any(&mut self) -> &mut dyn core::any::Any {
121
				self
122
			}
123

            
124
			fn type_id(&self) -> core::any::TypeId {
125
				core::any::Any::type_id(self)
126
			}
127
		}
128
	}
129
}
130

            
131
/// Something that provides access to the [`Extensions`] store.
132
///
133
/// This is a super trait of the [`Externalities`](crate::Externalities).
134
pub trait ExtensionStore {
135
	/// Tries to find a registered extension by the given `type_id` and returns it as a `&mut dyn
136
	/// Any`.
137
	///
138
	/// It is advised to use [`ExternalitiesExt::extension`](crate::ExternalitiesExt::extension)
139
	/// instead of this function to get type system support and automatic type downcasting.
140
	fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>;
141

            
142
	/// Register extension `extension` with specified `type_id`.
143
	///
144
	/// It should return error if extension is already registered.
145
	fn register_extension_with_type_id(
146
		&mut self,
147
		type_id: TypeId,
148
		extension: Box<dyn Extension>,
149
	) -> Result<(), Error>;
150

            
151
	/// Deregister extension with specified 'type_id' and drop it.
152
	///
153
	/// It should return error if extension is not registered.
154
	fn deregister_extension_by_type_id(&mut self, type_id: TypeId) -> Result<(), Error>;
155
}
156

            
157
/// Stores extensions that should be made available through the externalities.
158
#[derive(Default)]
159
pub struct Extensions {
160
	extensions: BTreeMap<TypeId, Box<dyn Extension>>,
161
}
162

            
163
#[cfg(feature = "std")]
164
impl std::fmt::Debug for Extensions {
165
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166
		write!(f, "Extensions: ({})", self.extensions.len())
167
	}
168
}
169

            
170
impl Extensions {
171
	/// Create new instance of `Self`.
172
	pub fn new() -> Self {
173
		Self::default()
174
	}
175

            
176
	/// Register the given extension.
177
	pub fn register<E: Extension>(&mut self, ext: E) {
178
		let type_id = ext.type_id();
179
		self.extensions.insert(type_id, Box::new(ext));
180
	}
181

            
182
	/// Register extension `extension` using the given `type_id`.
183
	pub fn register_with_type_id(
184
		&mut self,
185
		type_id: TypeId,
186
		extension: Box<dyn Extension>,
187
	) -> Result<(), Error> {
188
		match self.extensions.entry(type_id) {
189
			Entry::Vacant(vacant) => {
190
				vacant.insert(extension);
191
				Ok(())
192
			},
193
			Entry::Occupied(_) => Err(Error::ExtensionAlreadyRegistered),
194
		}
195
	}
196

            
197
	/// Return a mutable reference to the requested extension.
198
1876
	pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> {
199
1876
		self.extensions
200
1876
			.get_mut(&ext_type_id)
201
1876
			.map(DerefMut::deref_mut)
202
1876
			.map(Extension::as_mut_any)
203
1876
	}
204

            
205
	/// Deregister extension for the given `type_id`.
206
	///
207
	/// Returns `true` when the extension was registered.
208
	pub fn deregister(&mut self, type_id: TypeId) -> bool {
209
		self.extensions.remove(&type_id).is_some()
210
	}
211

            
212
	/// Returns a mutable iterator over all extensions.
213
2360028
	pub fn iter_mut(&mut self) -> impl Iterator<Item = (&TypeId, &mut Box<dyn Extension>)> {
214
2360028
		self.extensions.iter_mut()
215
2360028
	}
216

            
217
	/// Merge `other` into `self`.
218
	///
219
	/// If both contain the same extension, the extension instance of `other` will overwrite the
220
	/// instance found in `self`.
221
	pub fn merge(&mut self, other: Self) {
222
		self.extensions.extend(other.extensions);
223
	}
224
}
225

            
226
impl Extend<Extensions> for Extensions {
227
	fn extend<T: IntoIterator<Item = Extensions>>(&mut self, iter: T) {
228
		iter.into_iter()
229
			.for_each(|ext| self.extensions.extend(ext.extensions.into_iter()));
230
	}
231
}
232

            
233
#[cfg(test)]
234
mod tests {
235
	use super::*;
236

            
237
	decl_extension! {
238
		struct DummyExt(u32);
239
	}
240
	decl_extension! {
241
		struct DummyExt2(u32);
242
	}
243

            
244
	#[test]
245
	fn register_and_retrieve_extension() {
246
		let mut exts = Extensions::new();
247
		exts.register(DummyExt(1));
248
		exts.register(DummyExt2(2));
249

            
250
		let ext = exts.get_mut(TypeId::of::<DummyExt>()).expect("Extension is registered");
251
		let ext_ty = ext.downcast_mut::<DummyExt>().expect("Downcasting works");
252

            
253
		assert_eq!(ext_ty.0, 1);
254
	}
255

            
256
	#[test]
257
	fn register_box_extension() {
258
		let mut exts = Extensions::new();
259
		let box1: Box<dyn Extension> = Box::new(DummyExt(1));
260
		let box2: Box<dyn Extension> = Box::new(DummyExt2(2));
261
		exts.register(box1);
262
		exts.register(box2);
263

            
264
		{
265
			let ext = exts.get_mut(TypeId::of::<DummyExt>()).expect("Extension 1 is registered");
266
			let ext_ty = ext.downcast_mut::<DummyExt>().expect("Downcasting works for Extension 1");
267
			assert_eq!(ext_ty.0, 1);
268
		}
269
		{
270
			let ext2 = exts.get_mut(TypeId::of::<DummyExt2>()).expect("Extension 2 is registered");
271
			let ext_ty2 =
272
				ext2.downcast_mut::<DummyExt2>().expect("Downcasting works for Extension 2");
273
			assert_eq!(ext_ty2.0, 2);
274
		}
275
	}
276
}