#[doc(hidden)]
pub use sp_runtime::traits::{LookupError, BadOrigin};
#[doc(hidden)]
pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent};
#[macro_export]
macro_rules! decl_error {
(
$(#[$attr:meta])*
pub enum $error:ident
for $module:ident<
$generic:ident: $trait:path
$(, $inst_generic:ident: $instance:path)?
>
{
$(
$( #[doc = $doc_attr:tt] )*
$name:ident
),*
$(,)?
}
) => {
$(#[$attr])*
pub enum $error<$generic: $trait $(, $inst_generic: $instance)?> {
#[doc(hidden)]
__Ignore(
$crate::sp_std::marker::PhantomData<($generic, $( $inst_generic)?)>,
$crate::Never,
),
$(
$( #[doc = $doc_attr] )*
$name
),*
}
impl<$generic: $trait $(, $inst_generic: $instance)?> $crate::sp_std::fmt::Debug
for $error<$generic $(, $inst_generic)?>
{
fn fmt(&self, f: &mut $crate::sp_std::fmt::Formatter<'_>) -> $crate::sp_std::fmt::Result {
f.write_str(self.as_str())
}
}
impl<$generic: $trait $(, $inst_generic: $instance)?> $error<$generic $(, $inst_generic)?> {
fn as_u8(&self) -> u8 {
$crate::decl_error! {
@GENERATE_AS_U8
self
$error
{}
0,
$( $name ),*
}
}
fn as_str(&self) -> &'static str {
match self {
Self::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"),
$(
$error::$name => stringify!($name),
)*
}
}
}
impl<$generic: $trait $(, $inst_generic: $instance)?> From<$error<$generic $(, $inst_generic)?>>
for &'static str
{
fn from(err: $error<$generic $(, $inst_generic)?>) -> &'static str {
err.as_str()
}
}
impl<$generic: $trait $(, $inst_generic: $instance)?> From<$error<$generic $(, $inst_generic)?>>
for $crate::sp_runtime::DispatchError
{
fn from(err: $error<$generic $(, $inst_generic)?>) -> Self {
let index = <$generic::PalletInfo as $crate::traits::PalletInfo>
::index::<$module<$generic $(, $inst_generic)?>>()
.expect("Every active module has an index in the runtime; qed") as u8;
$crate::sp_runtime::DispatchError::Module {
index,
error: err.as_u8(),
message: Some(err.as_str()),
}
}
}
impl<$generic: $trait $(, $inst_generic: $instance)?> $crate::error::ModuleErrorMetadata
for $error<$generic $(, $inst_generic)?>
{
fn metadata() -> &'static [$crate::error::ErrorMetadata] {
&[
$(
$crate::error::ErrorMetadata {
name: $crate::error::DecodeDifferent::Encode(stringify!($name)),
documentation: $crate::error::DecodeDifferent::Encode(&[
$( $doc_attr ),*
]),
}
),*
]
}
}
};
(@GENERATE_AS_U8
$self:ident
$error:ident
{ $( $generated:tt )* }
$index:expr,
$name:ident
$( , $rest:ident )*
) => {
$crate::decl_error! {
@GENERATE_AS_U8
$self
$error
{
$( $generated )*
$error::$name => $index,
}
$index + 1,
$( $rest ),*
}
};
(@GENERATE_AS_U8
$self:ident
$error:ident
{ $( $generated:tt )* }
$index:expr,
) => {
match $self {
$error::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"),
$( $generated )*
}
}
}