aux_error/
lib.rs

1/// 定义错误类型,携带 code、msg 和一个自定义类型的数据
2///
3/// # Example
4///
5/// ```
6/// aux_svc::define_error! {
7///     // 可用于传递 i18n 参数
8///     pub AppError<aux_i18n::Args<'static>> {
9///         MissBody(1, "miss_body");
10///         InvalidParams(2, "invalid_params");
11///     }
12/// }
13///
14/// println!(AppError::MissBody(None)); // 无 i18n 参数
15/// println!(AppError::InvalidParams(Some(fluent::fluent_args![ // 传递 i18n 参数
16///     "field" => "name",
17/// ])))
18/// ```
19#[macro_export] macro_rules! define_error {
20    (
21        $(#[$docs:meta])*
22        $vis:vis $enum_name:ident<$args_type:ty> {
23            $($name:ident($code:expr, $msg:expr);)+
24        }
25    ) => {
26        $(#[$docs])*
27        #[derive(Debug)]
28        $vis enum $enum_name {
29            $(
30                $name(Option<$args_type>),
31            )+
32
33            Unknown(anyhow::Error),
34        }
35
36        impl $enum_name {
37            pub fn code(&self) -> Option<i32> {
38                match self {
39                    $($enum_name::$name(..) => Some($code),)+
40                    $enum_name::Unknown(..) => None,
41                }
42            }
43
44            pub fn msg(&self) -> Option<&'static str> {
45                match self {
46                    $($enum_name::$name(..) => Some($msg),)+
47                    $enum_name::Unknown(..) => None,
48                }
49            }
50
51            pub fn args(&self) -> Option<&$args_type> {
52                match self {
53                    $($enum_name::$name(a) => a.as_ref(),)+
54                    $enum_name::Unknown(..) => None,
55                }
56            }
57        }
58
59        impl<T> From<T> for $enum_name
60        where
61            T: Into<anyhow::Error>
62        {
63            fn from(t: T) -> Self {
64                $enum_name::Unknown(t.into())
65            }
66        }
67    }
68}