use super::transaction_extension::{TransactionExtension, TransactionExtensionError};
use alloc::borrow::ToOwned;
use alloc::string::String;
use alloc::vec::Vec;
use scale_type_resolver::TypeResolver;
pub trait TransactionExtensions<Resolver: TypeResolver> {
fn contains_extension(&self, name: &str) -> bool;
fn encode_extension_value_to(
&self,
name: &str,
type_id: Resolver::TypeId,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), TransactionExtensionsError>;
fn encode_extension_value_for_signer_payload_to(
&self,
name: &str,
type_id: Resolver::TypeId,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), TransactionExtensionsError> {
self.encode_extension_value_to(name, type_id, type_resolver, out)
}
fn encode_extension_implicit_to(
&self,
name: &str,
type_id: Resolver::TypeId,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), TransactionExtensionsError>;
}
#[derive(Debug, thiserror::Error)]
pub enum TransactionExtensionsError {
#[error("Cannot encode transaction extension '{0}': This extension could not be found")]
NotFound(String),
#[error("Cannot encode transaction extension '{extension_name}': {error}")]
Other {
extension_name: String,
error: TransactionExtensionError,
},
}
impl<Resolver: TypeResolver> TransactionExtensions<Resolver> for () {
fn contains_extension(&self, _name: &str) -> bool {
false
}
fn encode_extension_value_to(
&self,
name: &str,
_type_id: <Resolver as TypeResolver>::TypeId,
_type_resolver: &Resolver,
_out: &mut Vec<u8>,
) -> Result<(), TransactionExtensionsError> {
Err(TransactionExtensionsError::NotFound(name.to_owned()))
}
fn encode_extension_implicit_to(
&self,
name: &str,
_type_id: <Resolver as TypeResolver>::TypeId,
_type_resolver: &Resolver,
_out: &mut Vec<u8>,
) -> Result<(), TransactionExtensionsError> {
Err(TransactionExtensionsError::NotFound(name.to_owned()))
}
}
macro_rules! impl_tuples {
($($ident:ident $index:tt),*) => {
impl <Resolver: TypeResolver $(,$ident)*> TransactionExtensions<Resolver> for ($($ident,)*)
where
$($ident: TransactionExtension<Resolver>,)*
{
fn contains_extension(&self, name: &str) -> bool {
$(
if $ident::NAME == name {
return true
}
)*
false
}
fn encode_extension_value_to(
&self,
name: &str,
type_id: <Resolver as TypeResolver>::TypeId,
type_resolver: &Resolver,
out: &mut Vec<u8>
) -> Result<(), TransactionExtensionsError> {
let len = out.len();
$(
if $ident::NAME == name {
return self.$index.encode_value_to(type_id, type_resolver, out)
.map_err(|e| {
out.truncate(len);
TransactionExtensionsError::Other {
extension_name: name.to_owned(),
error: e,
}
});
}
)*
Err(TransactionExtensionsError::NotFound(name.to_owned()))
}
fn encode_extension_value_for_signer_payload_to(
&self,
name: &str,
type_id: <Resolver as TypeResolver>::TypeId,
type_resolver: &Resolver,
out: &mut Vec<u8>
) -> Result<(), TransactionExtensionsError> {
let len = out.len();
$(
if $ident::NAME == name {
return self.$index.encode_value_for_signer_payload_to(type_id, type_resolver, out)
.map_err(|e| {
out.truncate(len);
TransactionExtensionsError::Other {
extension_name: name.to_owned(),
error: e,
}
});
}
)*
Err(TransactionExtensionsError::NotFound(name.to_owned()))
}
fn encode_extension_implicit_to(
&self,
name: &str,
type_id: <Resolver as TypeResolver>::TypeId,
type_resolver: &Resolver,
out: &mut Vec<u8>
) -> Result<(), TransactionExtensionsError> {
let len = out.len();
$(
if $ident::NAME == name {
return self.$index.encode_implicit_to(type_id, type_resolver, out)
.map_err(|e| {
out.truncate(len);
TransactionExtensionsError::Other {
extension_name: name.to_owned(),
error: e,
}
});
}
)*
Err(TransactionExtensionsError::NotFound(name.to_owned()))
}
}
}
}
#[rustfmt::skip]
const _: () = {
impl_tuples!(A 0);
impl_tuples!(A 0, B 1);
impl_tuples!(A 0, B 1, C 2);
impl_tuples!(A 0, B 1, C 2, D 3);
impl_tuples!(A 0, B 1, C 2, D 3, E 4);
impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5);
impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
};