Skip to main content

flare_core/common/error/
localized.rs

1//! 国际化错误信息结构
2
3use super::code::{ErrorCategory, ErrorCode};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::fmt;
7
8/// 国际化错误信息结构
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct LocalizedError {
11    /// 错误代码
12    pub code: ErrorCode,
13    /// 错误原因(用于国际化)
14    pub reason: String,
15    /// 错误详情(可选,用于调试)
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub details: Option<String>,
18    /// 错误参数(用于国际化插值)
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub params: Option<HashMap<String, String>>,
21    /// 错误时间戳
22    #[serde(with = "chrono::serde::ts_milliseconds")]
23    pub timestamp: chrono::DateTime<chrono::Utc>,
24}
25
26impl LocalizedError {
27    /// 创建新的本地化错误
28    pub fn new(code: ErrorCode, reason: impl Into<String>) -> Self {
29        Self {
30            code,
31            reason: reason.into(),
32            details: None,
33            params: None,
34            timestamp: chrono::Utc::now(),
35        }
36    }
37
38    /// 添加错误详情
39    #[must_use]
40    pub fn with_details(mut self, details: impl Into<String>) -> Self {
41        self.details = Some(details.into());
42        self
43    }
44
45    /// 添加错误参数
46    #[must_use]
47    pub fn with_params(mut self, params: HashMap<String, String>) -> Self {
48        self.params = Some(params);
49        self
50    }
51
52    /// 添加单个参数
53    #[must_use]
54    pub fn with_param(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
55        if self.params.is_none() {
56            self.params = Some(HashMap::new());
57        }
58        if let Some(ref mut params) = self.params {
59            params.insert(key.into(), value.into());
60        }
61        self
62    }
63
64    /// 获取错误代码的数字值
65    #[inline]
66    pub fn code_value(&self) -> u32 {
67        self.code.as_u32()
68    }
69
70    /// 获取错误代码的字符串标识符
71    #[inline]
72    pub fn code_str(&self) -> &'static str {
73        self.code.as_str()
74    }
75
76    /// 获取错误类别
77    #[inline]
78    pub fn category(&self) -> ErrorCategory {
79        self.code.category()
80    }
81
82    /// 判断是否为可重试的错误
83    #[inline]
84    pub fn is_retryable(&self) -> bool {
85        self.code.is_retryable()
86    }
87}
88
89impl fmt::Display for LocalizedError {
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        write!(f, "{}: {}", self.code.as_str(), self.reason)
92    }
93}