pub trait ChainExtensionInstance {
type Instance;
fn instantiate() -> Self::Instance;
}
pub trait ChainExtension {
type ErrorCode: ink_env::chain_extension::FromStatusCode;
}
#[doc(hidden)]
pub trait IsResultType: private::IsResultSealed {
type Ok;
type Err;
}
impl<T, E> private::IsResultSealed for Result<T, E> {}
impl<T, E> IsResultType for Result<T, E> {
type Ok = T;
type Err = E;
}
pub trait Output<const IS_RESULT: bool, const HANDLE_STATUS: bool, T, E>:
private::OutputSealed
{
type ReturnType;
}
pub struct ValueReturned;
impl private::OutputSealed for ValueReturned {}
impl<T, E> Output<false, false, T, E> for ValueReturned {
type ReturnType = T;
}
impl<T, E> Output<false, true, T, E> for ValueReturned {
type ReturnType = core::result::Result<T, E>;
}
impl<T, E> Output<true, false, T, E> for ValueReturned {
type ReturnType = T;
}
impl<T, E> Output<true, true, T, E> for ValueReturned {
type ReturnType = T;
}
mod private {
pub trait IsResultSealed {}
pub trait OutputSealed {}
}
#[macro_export]
macro_rules! combine_extensions {
($(#[$meta:meta])* $vis:vis struct $name:ident {
$($(#[$field_meta:meta])* $field_vis:vis $field_name:ident: $field_type:ty,)*
}) => {
$(#[$meta])*
#[::ink::scale_derive(TypeInfo)]
$vis struct $name {
$($(#[$field_meta])* $field_vis $field_name: $field_type,)*
}
const _: () = {
pub struct Private {
$($(#[$field_meta])* $field_vis $field_name: <$field_type as ::ink::ChainExtensionInstance>::Instance,)*
}
impl ::ink::ChainExtensionInstance for $name {
type Instance = Private;
fn instantiate() -> Self::Instance {
Self::Instance {
$($field_name: <$field_type as ::ink::ChainExtensionInstance>::instantiate(),)*
}
}
}
};
}
}