1#![allow(missing_docs)]
2
3#[derive(Debug)]
8pub enum RecursiveError {
9 Root {
10 context: &'static str,
11 source: Box<crate::Error>,
12 },
13 TransactionContext {
14 context: &'static str,
15 source: Box<crate::transaction_context::Error>,
16 },
17 E2e {
18 context: &'static str,
19 source: Box<crate::e2e_identity::Error>,
20 },
21 Mls {
22 context: &'static str,
23 source: Box<crate::mls::Error>,
24 },
25 MlsClient {
26 context: &'static str,
27 source: Box<crate::mls::session::Error>,
28 },
29 MlsConversation {
30 context: &'static str,
31 source: Box<crate::mls::conversation::Error>,
32 },
33 MlsCredential {
34 context: &'static str,
35 source: Box<crate::mls::credential::Error>,
36 },
37 MlsCredentialRef {
38 context: &'static str,
39 source: Box<crate::mls::credential::credential_ref::Error>,
40 },
41 #[cfg(test)]
42 Test(Box<crate::test_utils::TestError>),
43}
44
45impl RecursiveError {
46 pub fn root<E: Into<crate::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
47 move |into_source| Self::Root {
48 context,
49 source: Box::new(into_source.into()),
50 }
51 }
52
53 pub fn transaction<E: Into<crate::transaction_context::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
54 move |into_source| Self::TransactionContext {
55 context,
56 source: Box::new(into_source.into()),
57 }
58 }
59
60 pub fn e2e_identity<E: Into<crate::e2e_identity::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
61 move |into_source| Self::E2e {
62 context,
63 source: Box::new(into_source.into()),
64 }
65 }
66
67 pub fn mls<E: Into<crate::mls::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
68 move |into_source| Self::Mls {
69 context,
70 source: Box::new(into_source.into()),
71 }
72 }
73
74 pub fn mls_client<E: Into<crate::mls::session::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
75 move |into_source| Self::MlsClient {
76 context,
77 source: Box::new(into_source.into()),
78 }
79 }
80
81 pub fn mls_conversation<E: Into<crate::mls::conversation::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
82 move |into_source| Self::MlsConversation {
83 context,
84 source: Box::new(into_source.into()),
85 }
86 }
87
88 pub fn mls_credential<E: Into<crate::mls::credential::Error>>(context: &'static str) -> impl FnOnce(E) -> Self {
89 move |into_source| Self::MlsCredential {
90 context,
91 source: Box::new(into_source.into()),
92 }
93 }
94
95 pub fn mls_credential_ref<E: Into<crate::mls::credential::credential_ref::Error>>(
96 context: &'static str,
97 ) -> impl FnOnce(E) -> Self {
98 move |into_source| Self::MlsCredentialRef {
99 context,
100 source: Box::new(into_source.into()),
101 }
102 }
103}
104
105impl std::fmt::Display for RecursiveError {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 let context = match self {
108 RecursiveError::Root { context, .. } => context,
109 RecursiveError::E2e { context, .. } => context,
110 RecursiveError::Mls { context, .. } => context,
111 RecursiveError::MlsClient { context, .. } => context,
112 RecursiveError::MlsConversation { context, .. } => context,
113 RecursiveError::MlsCredential { context, .. } => context,
114 RecursiveError::MlsCredentialRef { context, .. } => context,
115 RecursiveError::TransactionContext { context, .. } => context,
116 #[cfg(test)]
117 RecursiveError::Test(e) => return (*e).fmt(f),
118 };
119 write!(f, "{context}")
120 }
121}
122
123impl std::error::Error for RecursiveError {
124 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
125 match self {
126 RecursiveError::Root { source, .. } => Some(source.as_ref()),
127 RecursiveError::E2e { source, .. } => Some(source.as_ref()),
128 RecursiveError::Mls { source, .. } => Some(source.as_ref()),
129 RecursiveError::MlsClient { source, .. } => Some(source.as_ref()),
130 RecursiveError::MlsConversation { source, .. } => Some(source.as_ref()),
131 RecursiveError::MlsCredential { source, .. } => Some(source.as_ref()),
132 RecursiveError::MlsCredentialRef { source, .. } => Some(source.as_ref()),
133 RecursiveError::TransactionContext { source, .. } => Some(source.as_ref()),
134 #[cfg(test)]
135 RecursiveError::Test(source) => Some(source.as_ref()),
136 }
137 }
138}
139
140pub trait ToRecursiveError {
146 fn construct_recursive(self, context: &'static str) -> RecursiveError;
148}
149
150macro_rules! impl_to_recursive_error_for {
151 ($($for:path => $variant:ident),+ $(,)?) => {
152 $(
153 impl ToRecursiveError for $for {
154 fn construct_recursive(self, context: &'static str) -> RecursiveError {
155 RecursiveError::$variant {
156 context,
157 source: Box::new(self),
158 }
159 }
160 }
161 )+
162 };
163}
164
165impl_to_recursive_error_for!(
166 crate::Error => Root,
167 crate::e2e_identity::Error => E2e,
168 crate::mls::Error => Mls,
169 crate::mls::session::Error => MlsClient,
170 crate::mls::conversation::Error => MlsConversation,
171 crate::mls::credential::Error => MlsCredential,
172 crate::mls::credential::credential_ref::Error => MlsCredentialRef,
173 crate::transaction_context::Error => TransactionContext,
174);