axum_resp_result/resp_result/
try_op.rs1use std::{
2 convert::Infallible,
3 ops::{ControlFlow, FromResidual, Try},
4};
5#[cfg(feature = "tracing")]
6use trace::{event, Level};
7
8use crate::RespError;
9
10use super::RespResult;
11
12impl<T, E: RespError> Try for RespResult<T, E> {
13 type Output = T;
14
15 type Residual = RespResult<Infallible, E>;
16
17 #[inline]
18 fn from_output(output: Self::Output) -> Self {
19 Self::Success(output)
20 }
21 #[inline]
22 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
23 match self {
24 RespResult::Success(data) => {
25 #[cfg(feature = "tracing")]
26 event!(Level::TRACE, control_flow = "Continue");
27 ControlFlow::Continue(data)
28 }
29 RespResult::Err(e) => {
30 #[cfg(feature = "tracing")]
31 event!(Level::TRACE, control_flow = "Break");
32 ControlFlow::Break(RespResult::Err(e))
33 }
34 }
35 }
36}
37
38impl<T, E, Ei> FromResidual<RespResult<Infallible, Ei>> for RespResult<T, E>
39where
40 E: From<Ei>,
41{
42 #[inline]
43 fn from_residual(residual: RespResult<Infallible, Ei>) -> Self {
44 match residual {
45 RespResult::Err(e) => Self::Err(From::from(e)),
46 RespResult::Success(_) => unreachable!(),
47 }
48 }
49}
50
51impl<T, E, F> FromResidual<Result<Infallible, E>> for RespResult<T, F>
52where
53 F: From<E>,
54{
55 #[inline]
56 fn from_residual(residual: Result<Infallible, E>) -> Self {
57 match residual {
58 Err(e) => Self::Err(F::from(e)),
59 Ok(_) => unreachable!(),
60 }
61 }
62}
63
64impl<T, E, F> FromResidual<RespResult<Infallible, E>> for Result<T, F>
65where
66 F: From<E>,
67{
68 #[inline]
69 fn from_residual(residual: RespResult<Infallible, E>) -> Self {
70 match residual {
71 RespResult::Err(err) => Result::Err(F::from(err)),
72 RespResult::Success(_) => unreachable!(),
73 }
74 }
75}
76
77#[cfg(test)]
78mod test {
79 use crate::{RespError, RespResult};
80
81 struct A;
82 struct B;
83
84 impl From<A> for MockA {
85 fn from(a: A) -> Self {
86 MockA::A(a)
87 }
88 }
89
90 impl From<B> for MockA {
91 fn from(v: B) -> Self {
92 MockA::B(v)
93 }
94 }
95
96 enum MockA {
97 A(A),
98 B(B),
99 }
100 impl RespError for MockA {
101 fn log_message(&self) -> std::borrow::Cow<'static, str> {
102 "MockA".into()
103 }
104
105 #[cfg(feature = "extra-error")]
106 type ExtraMessage = String;
107 #[cfg(feature = "extra-error")]
108 fn extra_message(&self) -> Self::ExtraMessage {
109 String::new()
110 }
111 }
112
113 fn _testb() -> RespResult<u32, MockA> {
115 let a = Result::<_, A>::Ok(11u32)?;
116 let _b = RespResult::<_, MockA>::ok(a)?;
117 let c = Result::<u32, B>::Err(B)?;
118
119 RespResult::Success(c)
120 }
121}