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 encode_extension_value_to(
33 &self,
34 name: &str,
35 type_id: Resolver::TypeId,
36 type_resolver: &Resolver,
37 out: &mut Vec<u8>,
38 ) -> Result<(), TransactionExtensionsError>;
39
40 fn encode_extension_value_for_signer_payload_to(
51 &self,
52 name: &str,
53 type_id: Resolver::TypeId,
54 type_resolver: &Resolver,
55 out: &mut Vec<u8>,
56 ) -> Result<(), TransactionExtensionsError> {
57 self.encode_extension_value_to(name, type_id, type_resolver, out)
58 }
59
60 fn encode_extension_implicit_to(
65 &self,
66 name: &str,
67 type_id: Resolver::TypeId,
68 type_resolver: &Resolver,
69 out: &mut Vec<u8>,
70 ) -> Result<(), TransactionExtensionsError>;
71}
72
73#[derive(Debug, thiserror::Error)]
75pub enum TransactionExtensionsError {
76 #[error("Cannot encode transaction extension '{0}': This extension could not be found")]
78 NotFound(String),
79 #[error("Cannot encode transaction extension '{extension_name}': {error}")]
81 Other {
82 extension_name: String,
84 error: TransactionExtensionError,
86 },
87}
88
89impl<Resolver: TypeResolver> TransactionExtensions<Resolver> for () {
91 fn contains_extension(&self, _name: &str) -> bool {
92 false
93 }
94
95 fn encode_extension_value_to(
96 &self,
97 name: &str,
98 _type_id: <Resolver as TypeResolver>::TypeId,
99 _type_resolver: &Resolver,
100 _out: &mut Vec<u8>,
101 ) -> Result<(), TransactionExtensionsError> {
102 Err(TransactionExtensionsError::NotFound(name.to_owned()))
103 }
104
105 fn encode_extension_implicit_to(
106 &self,
107 name: &str,
108 _type_id: <Resolver as TypeResolver>::TypeId,
109 _type_resolver: &Resolver,
110 _out: &mut Vec<u8>,
111 ) -> Result<(), TransactionExtensionsError> {
112 Err(TransactionExtensionsError::NotFound(name.to_owned()))
113 }
114}
115
116macro_rules! impl_tuples {
119 ($($ident:ident $index:tt),*) => {
120 impl <Resolver: TypeResolver $(,$ident)*> TransactionExtensions<Resolver> for ($($ident,)*)
121 where
122 $($ident: TransactionExtension<Resolver>,)*
123 {
124 fn contains_extension(&self, name: &str) -> bool {
125 $(
126 if $ident::NAME == name {
127 return true
128 }
129 )*
130 false
131 }
132
133 fn encode_extension_value_to(
134 &self,
135 name: &str,
136 type_id: <Resolver as TypeResolver>::TypeId,
137 type_resolver: &Resolver,
138 out: &mut Vec<u8>
139 ) -> Result<(), TransactionExtensionsError> {
140 let len = out.len();
141
142 $(
143 if $ident::NAME == name {
144 return self.$index.encode_value_to(type_id, type_resolver, out)
145 .map_err(|e| {
146 out.truncate(len);
150 TransactionExtensionsError::Other {
151 extension_name: name.to_owned(),
152 error: e,
153 }
154 });
155 }
156 )*
157
158 Err(TransactionExtensionsError::NotFound(name.to_owned()))
159 }
160
161 fn encode_extension_value_for_signer_payload_to(
162 &self,
163 name: &str,
164 type_id: <Resolver as TypeResolver>::TypeId,
165 type_resolver: &Resolver,
166 out: &mut Vec<u8>
167 ) -> Result<(), TransactionExtensionsError> {
168 let len = out.len();
169
170 $(
171 if $ident::NAME == name {
172 return self.$index.encode_value_for_signer_payload_to(type_id, type_resolver, out)
173 .map_err(|e| {
174 out.truncate(len);
178 TransactionExtensionsError::Other {
179 extension_name: name.to_owned(),
180 error: e,
181 }
182 });
183 }
184 )*
185
186 Err(TransactionExtensionsError::NotFound(name.to_owned()))
187 }
188
189 fn encode_extension_implicit_to(
190 &self,
191 name: &str,
192 type_id: <Resolver as TypeResolver>::TypeId,
193 type_resolver: &Resolver,
194 out: &mut Vec<u8>
195 ) -> Result<(), TransactionExtensionsError> {
196 let len = out.len();
197
198 $(
199 if $ident::NAME == name {
200 return self.$index.encode_implicit_to(type_id, type_resolver, out)
201 .map_err(|e| {
202 out.truncate(len);
206 TransactionExtensionsError::Other {
207 extension_name: name.to_owned(),
208 error: e,
209 }
210 });
211 }
212 )*
213
214 Err(TransactionExtensionsError::NotFound(name.to_owned()))
215 }
216 }
217 }
218}
219
220#[rustfmt::skip]
221const _: () = {
222 impl_tuples!(A 0);
223 impl_tuples!(A 0, B 1);
224 impl_tuples!(A 0, B 1, C 2);
225 impl_tuples!(A 0, B 1, C 2, D 3);
226 impl_tuples!(A 0, B 1, C 2, D 3, E 4);
227 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5);
228 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
229 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
230 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
231 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
232 impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
233 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);
234 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);
235 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);
236 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);
237 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);
238 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);
239 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);
240 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);
241 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);
242 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);
243 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);
244 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);
245 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);
246 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);
247 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);
248};