solana_decode_error/lib.rs
1//! Converting custom error codes to enums.
2
3use num_traits::FromPrimitive;
4
5/// Allows custom errors to be decoded back to their original enum.
6///
7/// Some Solana error enums, like [`ProgramError`], include a `Custom` variant,
8/// like [`ProgramError::Custom`], that contains a `u32` error code. This code
9/// may represent any error that is not covered by the error enum's named
10/// variants. It is common for programs to convert their own error enums to an
11/// error code and store it in the `Custom` variant, possibly with the help of
12/// the [`ToPrimitive`] trait.
13///
14/// This trait builds on the [`FromPrimitive`] trait to help convert those error
15/// codes to the original error enum they represent.
16///
17/// As this allows freely converting `u32` to any type that implements
18/// `FromPrimitive`, it is only used correctly when the caller is certain of the
19/// original error type.
20///
21/// [`ProgramError`]: https://docs.rs/solana-program-error/latest/solana_program_error/enum.ProgramError.html
22/// [`ProgramError::Custom`]: https://docs.rs/solana-program-error/latest/solana_program_error/enum.ProgramError.html#variant.Custom
23/// [`ToPrimitive`]: num_traits::ToPrimitive
24#[deprecated(since = "2.3.0", note = "Use `num_traits::FromPrimitive` instead")]
25pub trait DecodeError<E> {
26 fn decode_custom_error_to_enum(custom: u32) -> Option<E>
27 where
28 E: FromPrimitive,
29 {
30 E::from_u32(custom)
31 }
32 fn type_of() -> &'static str;
33}
34
35#[cfg(test)]
36#[allow(deprecated)]
37mod tests {
38 use {super::*, num_derive::FromPrimitive};
39
40 #[test]
41 fn test_decode_custom_error_to_enum() {
42 #[derive(Debug, FromPrimitive, PartialEq, Eq)]
43 enum TestEnum {
44 A,
45 B,
46 C,
47 }
48 impl<T> DecodeError<T> for TestEnum {
49 fn type_of() -> &'static str {
50 "TestEnum"
51 }
52 }
53 assert_eq!(TestEnum::decode_custom_error_to_enum(0), Some(TestEnum::A));
54 assert_eq!(TestEnum::decode_custom_error_to_enum(1), Some(TestEnum::B));
55 assert_eq!(TestEnum::decode_custom_error_to_enum(2), Some(TestEnum::C));
56 let option: Option<TestEnum> = TestEnum::decode_custom_error_to_enum(3);
57 assert_eq!(option, None);
58 }
59}