gp_externalities/
extensions.rs1use crate::Error;
26use sp_std::{
27 any::{Any, TypeId},
28 boxed::Box,
29 collections::btree_map::{BTreeMap, Entry},
30 ops::DerefMut,
31};
32
33pub trait Extension: Send + Any {
39 fn as_mut_any(&mut self) -> &mut dyn Any;
43}
44
45#[macro_export]
59macro_rules! decl_extension {
60 (
61 $( #[ $attr:meta ] )*
62 $vis:vis struct $ext_name:ident ($inner:ty);
63 ) => {
64 $( #[ $attr ] )*
65 $vis struct $ext_name (pub $inner);
66
67 impl $crate::Extension for $ext_name {
68 fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
69 self
70 }
71 }
72
73 impl std::ops::Deref for $ext_name {
74 type Target = $inner;
75
76 fn deref(&self) -> &Self::Target {
77 &self.0
78 }
79 }
80
81 impl std::ops::DerefMut for $ext_name {
82 fn deref_mut(&mut self) -> &mut Self::Target {
83 &mut self.0
84 }
85 }
86
87 impl From<$inner> for $ext_name {
88 fn from(inner: $inner) -> Self {
89 Self(inner)
90 }
91 }
92 };
93 (
94 $( #[ $attr:meta ] )*
95 $vis:vis struct $ext_name:ident;
96 ) => {
97 $( #[ $attr ] )*
98 $vis struct $ext_name;
99
100 impl $crate::Extension for $ext_name {
101 fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
102 self
103 }
104 }
105 }
106}
107
108pub trait ExtensionStore {
112 fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>;
118
119 fn register_extension_with_type_id(
123 &mut self,
124 type_id: TypeId,
125 extension: Box<dyn Extension>,
126 ) -> Result<(), Error>;
127
128 fn deregister_extension_by_type_id(&mut self, type_id: TypeId) -> Result<(), Error>;
132}
133
134#[derive(Default)]
136pub struct Extensions {
137 extensions: BTreeMap<TypeId, Box<dyn Extension>>,
138}
139
140#[cfg(feature = "std")]
141impl std::fmt::Debug for Extensions {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 write!(f, "Extensions: ({})", self.extensions.len())
144 }
145}
146
147impl Extensions {
148 pub fn new() -> Self {
150 Self::default()
151 }
152
153 pub fn register<E: Extension>(&mut self, ext: E) {
155 let type_id = ext.type_id();
156 self.extensions.insert(type_id, Box::new(ext));
157 }
158
159 pub fn register_with_type_id(
161 &mut self,
162 type_id: TypeId,
163 extension: Box<dyn Extension>,
164 ) -> Result<(), Error> {
165 match self.extensions.entry(type_id) {
166 Entry::Vacant(vacant) => {
167 vacant.insert(extension);
168 Ok(())
169 },
170 Entry::Occupied(_) => Err(Error::ExtensionAlreadyRegistered),
171 }
172 }
173
174 pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> {
176 self.extensions
177 .get_mut(&ext_type_id)
178 .map(DerefMut::deref_mut)
179 .map(Extension::as_mut_any)
180 }
181
182 pub fn deregister(&mut self, type_id: TypeId) -> bool {
186 self.extensions.remove(&type_id).is_some()
187 }
188
189 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&TypeId, &mut Box<dyn Extension>)> {
191 self.extensions.iter_mut()
192 }
193}
194
195impl Extend<Extensions> for Extensions {
196 fn extend<T: IntoIterator<Item = Extensions>>(&mut self, iter: T) {
197 iter.into_iter()
198 .for_each(|ext| self.extensions.extend(ext.extensions.into_iter()));
199 }
200}
201
202#[cfg(test)]
203mod tests {
204 use super::*;
205
206 decl_extension! {
207 struct DummyExt(u32);
208 }
209 decl_extension! {
210 struct DummyExt2(u32);
211 }
212
213 #[test]
214 fn register_and_retrieve_extension() {
215 let mut exts = Extensions::new();
216 exts.register(DummyExt(1));
217 exts.register(DummyExt2(2));
218
219 let ext = exts.get_mut(TypeId::of::<DummyExt>()).expect("Extension is registered");
220 let ext_ty = ext.downcast_mut::<DummyExt>().expect("Downcasting works");
221
222 assert_eq!(ext_ty.0, 1);
223 }
224}