1use super::transaction_extension::{TransactionExtension, TransactionExtensionError};
17use alloc::borrow::ToOwned;
18use alloc::string::String;
19use alloc::vec::Vec;
20use scale_type_resolver::TypeResolver;
21
22pub trait TransactionExtensions<Resolver: TypeResolver> {
25 fn contains_extension(&self, name: &str) -> bool;
27
28 fn is_authorization_extension(&self, _name: &str) -> bool {
32 false
33 }
34
35 fn encode_extension_value_to(
40 &self,
41 name: &str,
42 type_id: Resolver::TypeId,
43 type_resolver: &Resolver,
44 out: &mut Vec<u8>,
45 ) -> Result<(), TransactionExtensionsError>;
46
47 fn encode_extension_implicit_to(
52 &self,
53 name: &str,
54 type_id: Resolver::TypeId,
55 type_resolver: &Resolver,
56 out: &mut Vec<u8>,
57 ) -> Result<(), TransactionExtensionsError>;
58}
59
60#[derive(Debug, thiserror::Error)]
62pub enum TransactionExtensionsError {
63 #[error("Cannot encode transaction extension '{0}': This extension could not be found")]
65 NotFound(String),
66 #[error("Cannot encode transaction extension '{extension_name}': {error}")]
68 Other {
69 extension_name: String,
71 error: TransactionExtensionError,
73 },
74}
75
76impl<Resolver: TypeResolver> TransactionExtensions<Resolver> for () {
78 fn contains_extension(&self, _name: &str) -> bool {
79 false
80 }
81
82 fn encode_extension_value_to(
83 &self,
84 name: &str,
85 _type_id: <Resolver as TypeResolver>::TypeId,
86 _type_resolver: &Resolver,
87 _out: &mut Vec<u8>,
88 ) -> Result<(), TransactionExtensionsError> {
89 Err(TransactionExtensionsError::NotFound(name.to_owned()))
90 }
91
92 fn encode_extension_implicit_to(
93 &self,
94 name: &str,
95 _type_id: <Resolver as TypeResolver>::TypeId,
96 _type_resolver: &Resolver,
97 _out: &mut Vec<u8>,
98 ) -> Result<(), TransactionExtensionsError> {
99 Err(TransactionExtensionsError::NotFound(name.to_owned()))
100 }
101}
102
103macro_rules! impl_tuples {
106 ($($ident:ident $index:tt),*) => {
107 impl <Resolver: TypeResolver $(,$ident)*> TransactionExtensions<Resolver> for ($($ident,)*)
108 where
109 $($ident: TransactionExtension<Resolver>,)*
110 {
111 fn contains_extension(&self, name: &str) -> bool {
112 $(
113 if $ident::NAME == name {
114 return true
115 }
116 )*
117 false
118 }
119
120 fn is_authorization_extension(&self, name: &str) -> bool {
121 $(
122 if $ident::NAME == name {
123 return self.$index.is_authorization_extension()
124 }
125 )*
126 false
127 }
128
129 fn encode_extension_value_to(
130 &self,
131 name: &str,
132 type_id: <Resolver as TypeResolver>::TypeId,
133 type_resolver: &Resolver,
134 out: &mut Vec<u8>
135 ) -> Result<(), TransactionExtensionsError> {
136 let len = out.len();
137
138 $(
139 if $ident::NAME == name {
140 return self.$index.encode_value_to(type_id, type_resolver, out)
141 .map_err(|e| {
142 out.truncate(len);
146 TransactionExtensionsError::Other {
147 extension_name: name.to_owned(),
148 error: e,
149 }
150 });
151 }
152 )*
153
154 Err(TransactionExtensionsError::NotFound(name.to_owned()))
155 }
156
157 fn encode_extension_implicit_to(
158 &self,
159 name: &str,
160 type_id: <Resolver as TypeResolver>::TypeId,
161 type_resolver: &Resolver,
162 out: &mut Vec<u8>
163 ) -> Result<(), TransactionExtensionsError> {
164 let len = out.len();
165
166 $(
167 if $ident::NAME == name {
168 return self.$index.encode_implicit_to(type_id, type_resolver, out)
169 .map_err(|e| {
170 out.truncate(len);
174 TransactionExtensionsError::Other {
175 extension_name: name.to_owned(),
176 error: e,
177 }
178 });
179 }
180 )*
181
182 Err(TransactionExtensionsError::NotFound(name.to_owned()))
183 }
184 }
185 }
186}
187
188#[rustfmt::skip]
189const _: () = {
190 impl_tuples!(A 0);
191 impl_tuples!(A 0, B 1);
192 impl_tuples!(A 0, B 1, C 2);
193 impl_tuples!(A 0, B 1, C 2, D 3);
194 impl_tuples!(A 0, B 1, C 2, D 3, E 4);
195 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5);
196 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
197 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
198 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
199 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
200 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
201 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11);
202 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12);
203 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13);
204 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14);
205 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15);
206 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16);
207 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17);
208 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18);
209 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19);
210 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20);
211 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21);
212 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22);
213 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22, X 23);
214 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22, X 23, Y 24);
215 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22, X 23, Y 24, Z 25);
216};