telltale_runtime/effects/
handler_context.rs1use super::{ChoreoResult, ChoreographyError};
2
3impl ChoreographyError {
4 #[must_use]
6 pub fn with_protocol_context(
7 self,
8 protocol: &'static str,
9 role: &'static str,
10 phase: &'static str,
11 ) -> Self {
12 ChoreographyError::ProtocolContext {
13 protocol,
14 role,
15 phase,
16 inner: Box::new(self),
17 }
18 }
19
20 #[must_use]
22 pub fn with_role_context(self, role: &'static str, index: Option<u32>) -> Self {
23 ChoreographyError::RoleContext {
24 role,
25 index,
26 inner: Box::new(self),
27 }
28 }
29
30 #[must_use]
32 pub fn with_message_context(
33 self,
34 operation: &'static str,
35 message_type: &'static str,
36 direction: &'static str,
37 other_role: &'static str,
38 ) -> Self {
39 ChoreographyError::MessageContext {
40 operation,
41 message_type,
42 direction,
43 other_role,
44 inner: Box::new(self),
45 }
46 }
47
48 #[must_use]
50 pub fn with_context(self, context: impl Into<String>) -> Self {
51 ChoreographyError::WithContext {
52 context: context.into(),
53 inner: Box::new(self),
54 }
55 }
56
57 #[must_use]
59 pub fn root_cause(&self) -> &ChoreographyError {
60 match self {
61 ChoreographyError::ProtocolContext { inner, .. }
62 | ChoreographyError::RoleContext { inner, .. }
63 | ChoreographyError::MessageContext { inner, .. }
64 | ChoreographyError::WithContext { inner, .. } => inner.root_cause(),
65 _ => self,
66 }
67 }
68
69 #[must_use]
71 pub fn is_timeout(&self) -> bool {
72 matches!(self.root_cause(), ChoreographyError::Timeout(_))
73 }
74
75 #[must_use]
77 pub fn is_transport(&self) -> bool {
78 matches!(
79 self.root_cause(),
80 ChoreographyError::Transport(_)
81 | ChoreographyError::ChannelSendFailed { .. }
82 | ChoreographyError::ChannelClosed { .. }
83 | ChoreographyError::NoPeerChannel { .. }
84 )
85 }
86
87 #[must_use]
89 pub fn is_protocol_violation(&self) -> bool {
90 matches!(self.root_cause(), ChoreographyError::ProtocolViolation(_))
91 }
92
93 #[must_use]
95 pub fn is_serialization(&self) -> bool {
96 matches!(
97 self.root_cause(),
98 ChoreographyError::Serialization(_)
99 | ChoreographyError::LabelSerializationFailed { .. }
100 | ChoreographyError::MessageSerializationFailed { .. }
101 )
102 }
103}
104
105pub trait ContextExt<T> {
110 fn with_protocol_context(
112 self,
113 protocol: &'static str,
114 role: &'static str,
115 phase: &'static str,
116 ) -> ChoreoResult<T>;
117
118 fn with_role_context(self, role: &'static str, index: Option<u32>) -> ChoreoResult<T>;
120
121 fn with_message_context(
123 self,
124 operation: &'static str,
125 message_type: &'static str,
126 direction: &'static str,
127 other_role: &'static str,
128 ) -> ChoreoResult<T>;
129
130 fn with_context(self, context: impl Into<String>) -> ChoreoResult<T>;
132}
133
134impl<T> ContextExt<T> for ChoreoResult<T> {
135 fn with_protocol_context(
136 self,
137 protocol: &'static str,
138 role: &'static str,
139 phase: &'static str,
140 ) -> ChoreoResult<T> {
141 self.map_err(|e| e.with_protocol_context(protocol, role, phase))
142 }
143
144 fn with_role_context(self, role: &'static str, index: Option<u32>) -> ChoreoResult<T> {
145 self.map_err(|e| e.with_role_context(role, index))
146 }
147
148 fn with_message_context(
149 self,
150 operation: &'static str,
151 message_type: &'static str,
152 direction: &'static str,
153 other_role: &'static str,
154 ) -> ChoreoResult<T> {
155 self.map_err(|e| e.with_message_context(operation, message_type, direction, other_role))
156 }
157
158 fn with_context(self, context: impl Into<String>) -> ChoreoResult<T> {
159 self.map_err(|e| e.with_context(context))
160 }
161}