#error #derive-error #macro-derive #solana #attributes #spl #thiserror

spl-program-error

为 Solana 程序错误属性提供库以及用于创建它们的 derive 宏

9 个不稳定版本 (4 个重大更改)

0.5.0 2024 年 6 月 25 日
0.4.4 2024 年 7 月 11 日
0.4.1 2024 年 4 月 22 日
0.4.0 2024 年 3 月 28 日
0.1.0 2023 年 6 月 7 日

#1073神奇豆子

Download history 34006/week @ 2024-04-21 29056/week @ 2024-04-28 29055/week @ 2024-05-05 30728/week @ 2024-05-12 24079/week @ 2024-05-19 26482/week @ 2024-05-26 29636/week @ 2024-06-02 31223/week @ 2024-06-09 29809/week @ 2024-06-16 33337/week @ 2024-06-23 27686/week @ 2024-06-30 30842/week @ 2024-07-07 29890/week @ 2024-07-14 35585/week @ 2024-07-21 36555/week @ 2024-07-28 56359/week @ 2024-08-04

159,966 每月下载量
用于 451 个crate(7 个直接使用)

Apache-2.0

13KB

SPL 程序错误

用于在枚举上实现基于错误的特质的宏。

  • #[derive(IntoProgramError)]: 自动推导 From<Self> for solana_program::program_error::ProgramError 特质。
  • #[derive(DecodeError)]:自动推导特质solana_program::decode_error::DecodeError<T>
  • #[derive(PrintProgramError)]:自动推导特质solana_program::program_error::PrintProgramError
  • #[spl_program_error]:自动推导以下所有特质
    • 克隆
    • 调试
    • 等价
    • 解码错误
    • 转换为程序错误
    • 打印程序错误
    • thiserror::错误
    • num_derive::从原始类型派生
    • 部分等价

#[推导(转换为程序错误)]

此推导宏自动推导特质From<Self> for solana_program::program_error::ProgramError

您的枚举必须实现以下特质,以便此宏可以工作

  • 克隆
  • 调试
  • 等价
  • thiserror::错误
  • num_derive::从原始类型派生
  • 部分等价

示例代码

/// Example error
#[derive(
    Clone, Debug, Eq, IntoProgramError, thiserror::Error, num_derive::FromPrimitive, PartialEq,
)]
pub enum ExampleError {
    /// Mint has no mint authority
    #[error("Mint has no mint authority")]
    MintHasNoMintAuthority,
    /// Incorrect mint authority has signed the instruction
    #[error("Incorrect mint authority has signed the instruction")]
    IncorrectMintAuthority,
}

#[推导(解码错误)]

此推导宏自动推导特质solana_program::decode_error::DecodeError<T>

您的枚举必须实现以下特质,以便此宏可以工作

  • 克隆
  • 调试
  • 等价
  • IntoProgramError(如上所述)
  • thiserror::错误
  • num_derive::从原始类型派生
  • 部分等价

示例代码

/// Example error
#[derive(
    Clone,
    Debug,
    DecodeError,
    Eq,
    IntoProgramError,
    thiserror::Error,
    num_derive::FromPrimitive,
    PartialEq,
)]
pub enum ExampleError {
    /// Mint has no mint authority
    #[error("Mint has no mint authority")]
    MintHasNoMintAuthority,
    /// Incorrect mint authority has signed the instruction
    #[error("Incorrect mint authority has signed the instruction")]
    IncorrectMintAuthority,
}

#[推导(打印程序错误)]

此推导宏自动推导特质solana_program::program_error::PrintProgramError

您的枚举必须实现以下特质,以便此宏可以工作

  • 克隆
  • 调试
  • DecodeError<T>(如上所述)
  • 等价
  • IntoProgramError(如上所述)
  • thiserror::错误
  • num_derive::从原始类型派生
  • 部分等价

示例代码

/// Example error
#[derive(
    Clone,
    Debug,
    DecodeError,
    Eq,
    IntoProgramError,
    thiserror::Error,
    num_derive::FromPrimitive,
    PartialEq,
)]
pub enum ExampleError {
    /// Mint has no mint authority
    #[error("Mint has no mint authority")]
    MintHasNoMintAuthority,
    /// Incorrect mint authority has signed the instruction
    #[error("Incorrect mint authority has signed the instruction")]
    IncorrectMintAuthority,
}

#[spl_program_error]

确保您的程序定义的错误(通常表示为枚举)实现所需的特质并打印到程序日志中可能会很麻烦。

此过程宏将提供所有必要的实现

  • 克隆
  • 调试
  • 等价
  • thiserror::错误
  • num_derive::从原始类型派生
  • 部分等价

它还导入了所需的crates,因此您无需在程序中导入

  • num_derive
  • num_traits
  • thiserror

只需为您的枚举添加注解...

use solana_program_error_derive::*;

/// Example error
#[solana_program_error]
pub enum ExampleError {
    /// Mint has no mint authority
    #[error("Mint has no mint authority")]
    MintHasNoMintAuthority,
    /// Incorrect mint authority has signed the instruction
    #[error("Incorrect mint authority has signed the instruction")]
    IncorrectMintAuthority,
}

...然后获取

/// Example error
pub enum ExampleError {
    /// Mint has no mint authority
    #[error("Mint has no mint authority")]
    MintHasNoMintAuthority,
    /// Incorrect mint authority has signed the instruction
    #[error("Incorrect mint authority has signed the instruction")]
    IncorrectMintAuthority,
}
#[automatically_derived]
impl ::core::clone::Clone for ExampleError {
    #[inline]
    fn clone(&self) -> ExampleError {
        match self {
            ExampleError::MintHasNoMintAuthority => ExampleError::MintHasNoMintAuthority,
            ExampleError::IncorrectMintAuthority => ExampleError::IncorrectMintAuthority,
        }
    }
}
#[automatically_derived]
impl ::core::fmt::Debug for ExampleError {
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(
            f,
            match self {
                ExampleError::MintHasNoMintAuthority => "MintHasNoMintAuthority",
                ExampleError::IncorrectMintAuthority => "IncorrectMintAuthority",
            },
        )
    }
}
#[automatically_derived]
impl ::core::marker::StructuralEq for ExampleError {}
#[automatically_derived]
impl ::core::cmp::Eq for ExampleError {
    #[inline]
    #[doc(hidden)]
    #[no_coverage]
    fn assert_receiver_is_total_eq(&self) -> () {}
}
#[allow(unused_qualifications)]
impl std::error::Error for ExampleError {}
#[allow(unused_qualifications)]
impl std::fmt::Display for ExampleError {
    fn fmt(&self, __formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        #[allow(unused_variables, deprecated, clippy::used_underscore_binding)]
        match self {
            ExampleError::MintHasNoMintAuthority {} => {
                __formatter.write_fmt(format_args!("Mint has no mint authority"))
            }
            ExampleError::IncorrectMintAuthority {} => {
                __formatter
                    .write_fmt(
                        format_args!(
                            "Incorrect mint authority has signed the instruction"
                        ),
                    )
            }
        }
    }
}
#[allow(non_upper_case_globals, unused_qualifications)]
const _IMPL_NUM_FromPrimitive_FOR_ExampleError: () = {
    #[allow(clippy::useless_attribute)]
    #[allow(rust_2018_idioms)]
    extern crate num_traits as _num_traits;
    impl _num_traits::FromPrimitive for ExampleError {
        #[allow(trivial_numeric_casts)]
        #[inline]
        fn from_i64(n: i64) -> Option<Self> {
            if n == ExampleError::MintHasNoMintAuthority as i64 {
                Some(ExampleError::MintHasNoMintAuthority)
            } else if n == ExampleError::IncorrectMintAuthority as i64 {
                Some(ExampleError::IncorrectMintAuthority)
            } else {
                None
            }
        }
        #[inline]
        fn from_u64(n: u64) -> Option<Self> {
            Self::from_i64(n as i64)
        }
    }
};
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for ExampleError {}
#[automatically_derived]
impl ::core::cmp::PartialEq for ExampleError {
    #[inline]
    fn eq(&self, other: &ExampleError) -> bool {
        let __self_tag = ::core::intrinsics::discriminant_value(self);
        let __arg1_tag = ::core::intrinsics::discriminant_value(other);
        __self_tag == __arg1_tag
    }
}
impl From<ExampleError> for solana_program::program_error::ProgramError {
    fn from(e: ExampleError) -> Self {
        solana_program::program_error::ProgramError::Custom(e as u32)
    }
}
impl<T> solana_program::decode_error::DecodeError<T> for ExampleError {
    fn type_of() -> &'static str {
        "ExampleError"
    }
}
impl solana_program::program_error::PrintProgramError for ExampleError {
    fn print<E>(&self)
    where
        E: 'static + std::error::Error + solana_program::decode_error::DecodeError<E>
            + solana_program::program_error::PrintProgramError
            + num_traits::FromPrimitive,
    {
        match self {
            ExampleError::MintHasNoMintAuthority => {
                ::solana_program::log::sol_log("Mint has no mint authority")
            }
            ExampleError::IncorrectMintAuthority => {
                ::solana_program::log::sol_log(
                    "Incorrect mint authority has signed the instruction",
                )
            }
        }
    }
}

依赖项

~11–19MB
~264K SLoC