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