orion_error/traits/
conversion.rs

1use crate::{core::convert_error, DomainReason, StructError};
2
3pub trait ErrorConv<T, R: DomainReason>: Sized {
4    fn err_conv(self) -> Result<T, StructError<R>>;
5}
6
7pub trait ConvStructError<R: DomainReason>: Sized {
8    fn conv(self) -> StructError<R>;
9}
10
11impl<T, R1, R2> ErrorConv<T, R2> for Result<T, StructError<R1>>
12where
13    R1: DomainReason,
14    R2: DomainReason + From<R1>,
15{
16    fn err_conv(self) -> Result<T, StructError<R2>> {
17        match self {
18            Ok(o) => Ok(o),
19            Err(e) => Err(convert_error::<R1, R2>(e)),
20        }
21    }
22}
23
24impl<R1, R2> ConvStructError<R2> for StructError<R1>
25where
26    R1: DomainReason,
27    R2: DomainReason + From<R1>,
28{
29    fn conv(self) -> StructError<R2> {
30        convert_error::<R1, R2>(self)
31    }
32}
33
34pub trait ToStructError<R>
35where
36    R: DomainReason,
37{
38    fn to_err(self) -> StructError<R>;
39    fn err_result<T>(self) -> Result<T, StructError<R>>;
40}
41impl<R> ToStructError<R> for R
42where
43    R: DomainReason,
44{
45    fn to_err(self) -> StructError<R> {
46        StructError::from(self)
47    }
48    fn err_result<T>(self) -> Result<T, StructError<R>> {
49        Err(StructError::from(self))
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56    use crate::{ErrorCode, StructError, UvsReason};
57
58    // 定义测试用的 DomainReason
59    #[derive(Debug, Clone, PartialEq, serde::Serialize, thiserror::Error)]
60    enum TestReason {
61        #[error("test error")]
62        TestError,
63        #[error("{0}")]
64        Uvs(UvsReason),
65    }
66
67    impl ErrorCode for TestReason {
68        fn error_code(&self) -> i32 {
69            match self {
70                TestReason::TestError => 1001,
71                TestReason::Uvs(uvs) => uvs.error_code(),
72            }
73        }
74    }
75
76    impl From<UvsReason> for TestReason {
77        fn from(uvs: UvsReason) -> Self {
78            TestReason::Uvs(uvs)
79        }
80    }
81
82    // 定义另一个 DomainReason 用于测试转换
83    #[derive(Debug, Clone, PartialEq, serde::Serialize, thiserror::Error)]
84    enum AnotherReason {
85        #[error("another error")]
86        AnotherError,
87        #[error("{0}")]
88        Uvs(UvsReason),
89    }
90
91    impl ErrorCode for AnotherReason {
92        fn error_code(&self) -> i32 {
93            match self {
94                AnotherReason::AnotherError => 2001,
95                AnotherReason::Uvs(uvs) => uvs.error_code(),
96            }
97        }
98    }
99
100    impl From<UvsReason> for AnotherReason {
101        fn from(uvs: UvsReason) -> Self {
102            AnotherReason::Uvs(uvs)
103        }
104    }
105
106    impl From<TestReason> for AnotherReason {
107        fn from(test: TestReason) -> Self {
108            match test {
109                TestReason::TestError => AnotherReason::AnotherError,
110                TestReason::Uvs(uvs) => AnotherReason::Uvs(uvs),
111            }
112        }
113    }
114
115    #[test]
116    fn test_error_conv_trait() {
117        // 测试 ErrorConv trait 的 err_conv 方法
118        let original_result: Result<i32, StructError<TestReason>> =
119            Err(TestReason::TestError.to_err());
120
121        let converted_result: Result<i32, StructError<AnotherReason>> = original_result.err_conv();
122
123        assert!(converted_result.is_err());
124        let converted_error = converted_result.unwrap_err();
125        assert_eq!(converted_error.error_code(), 2001);
126
127        // 测试成功情况下的转换
128        let success_result: Result<i32, StructError<TestReason>> = Ok(42);
129        let converted_success: Result<i32, StructError<AnotherReason>> = success_result.err_conv();
130
131        assert!(converted_success.is_ok());
132        assert_eq!(converted_success.unwrap(), 42);
133    }
134
135    #[test]
136    fn test_conv_struct_error_trait() {
137        // 测试 ConvStructError trait 的 conv 方法
138        let original_error: StructError<TestReason> = TestReason::TestError.to_err();
139
140        let converted_error: StructError<AnotherReason> = original_error.conv();
141
142        assert_eq!(converted_error.error_code(), 2001);
143
144        // 测试带有 UvsReason 的转换
145        let uvs_error: StructError<TestReason> =
146            TestReason::Uvs(UvsReason::network_error("network failed")).to_err();
147
148        let converted_uvs_error: StructError<AnotherReason> = uvs_error.conv();
149
150        assert_eq!(converted_uvs_error.error_code(), 202);
151    }
152
153    #[test]
154    fn test_to_struct_error_trait() {
155        // 测试 ToStructError trait 的 to_err 方法
156        let reason = TestReason::TestError;
157        let error: StructError<TestReason> = reason.to_err();
158
159        assert_eq!(error.error_code(), 1001);
160
161        // 测试 ToStructError trait 的 err_result 方法
162        let reason2 = TestReason::TestError;
163        let result: Result<String, StructError<TestReason>> = reason2.err_result();
164
165        assert!(result.is_err());
166        let error_from_result = result.unwrap_err();
167        assert_eq!(error_from_result.error_code(), 1001);
168
169        // 测试使用 UvsReason
170        let uvs_reason1 = UvsReason::validation_error("invalid input");
171        let uvs_error: StructError<UvsReason> = uvs_reason1.to_err();
172
173        assert_eq!(uvs_error.error_code(), 100);
174
175        let uvs_reason2 = UvsReason::validation_error("invalid input");
176        let uvs_result: Result<i32, StructError<UvsReason>> = uvs_reason2.err_result();
177        assert!(uvs_result.is_err());
178        assert_eq!(uvs_result.unwrap_err().error_code(), 100);
179    }
180}