1#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
9use alloc::borrow::Cow;
10
11#[cfg(feature = "std")]
12use std::fmt;
13
14#[cfg(not(feature = "std"))]
15use core::fmt;
16
17use dcrypt_api::{Error as CoreError, Result as CoreResult};
18
19#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum Error {
22 Parameter {
24 name: Cow<'static, str>, reason: Cow<'static, str>, },
29
30 Length {
32 context: &'static str,
34 expected: usize,
36 actual: usize,
38 },
39
40 Authentication {
42 algorithm: &'static str,
44 },
45
46 NotImplemented {
48 feature: &'static str,
50 },
51
52 Processing {
54 operation: &'static str,
56 details: &'static str,
58 },
59
60 MacError {
62 algorithm: &'static str,
64 details: &'static str,
66 },
67
68 #[cfg(feature = "std")]
70 External {
71 source: &'static str,
73 details: String,
75 },
76
77 #[cfg(not(feature = "std"))]
78 External {
79 source: &'static str,
81 },
82
83 Other(&'static str),
85}
86
87impl Error {
89 pub fn param<N: Into<Cow<'static, str>>, R: Into<Cow<'static, str>>>(
91 name: N,
92 reason: R,
93 ) -> Self {
94 Error::Parameter {
95 name: name.into(),
96 reason: reason.into(),
97 }
98 }
99}
100
101pub type Result<T> = core::result::Result<T, Error>;
103
104pub type CipherResult<T> = Result<T>;
107pub type HashResult<T> = Result<T>;
109pub type MacResult<T> = Result<T>;
111
112impl fmt::Display for Error {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match self {
116 Error::Parameter { name, reason } => {
117 write!(f, "Invalid parameter '{}': {}", name, reason)
118 }
119 Error::Length {
120 context,
121 expected,
122 actual,
123 } => {
124 write!(
125 f,
126 "Invalid length for {}: expected {}, got {}",
127 context, expected, actual
128 )
129 }
130 Error::Authentication { algorithm } => {
131 write!(f, "Authentication failed for {}", algorithm)
132 }
133 Error::NotImplemented { feature } => {
134 write!(f, "Feature not implemented: {}", feature)
135 }
136 Error::Processing { operation, details } => {
137 write!(f, "Processing error in {}: {}", operation, details)
138 }
139 Error::MacError { algorithm, details } => {
140 write!(f, "MAC error in {}: {}", algorithm, details)
141 }
142 #[cfg(feature = "std")]
143 Error::External { source, details } => {
144 write!(f, "External error from {}: {}", source, details)
145 }
146 #[cfg(not(feature = "std"))]
147 Error::External { source } => {
148 write!(f, "External error from {}", source)
149 }
150 Error::Other(msg) => write!(f, "{}", msg),
151 }
152 }
153}
154
155#[cfg(feature = "std")]
157impl std::error::Error for Error {}
158
159impl From<Error> for CoreError {
161 fn from(err: Error) -> Self {
162 match err {
163 Error::Parameter { name, reason } => CoreError::InvalidParameter {
164 context: match name {
165 Cow::Borrowed(s) => s,
166 Cow::Owned(s) => Box::leak(s.into_boxed_str()),
167 },
168 #[cfg(feature = "std")]
169 message: reason.into_owned(),
170 },
171 Error::Length {
172 context,
173 expected,
174 actual,
175 } => CoreError::InvalidLength {
176 context,
177 expected,
178 actual,
179 },
180 Error::Authentication { algorithm } => CoreError::AuthenticationFailed {
181 context: algorithm,
182 #[cfg(feature = "std")]
183 message: "authentication failed".to_string(),
184 },
185 Error::NotImplemented { feature } => CoreError::NotImplemented { feature },
186 Error::Processing { operation, details } => CoreError::Other {
187 context: operation,
188 #[cfg(feature = "std")]
189 message: details.to_string(),
190 },
191 Error::MacError { algorithm, details } => CoreError::Other {
192 context: algorithm,
193 #[cfg(feature = "std")]
194 message: details.to_string(),
195 },
196 #[cfg(feature = "std")]
197 Error::External { source, details } => CoreError::Other {
198 context: source,
199 message: details,
200 },
201 #[cfg(not(feature = "std"))]
202 Error::External { source } => CoreError::Other {
203 context: source,
204 #[cfg(feature = "std")]
205 message: "external error".to_string(),
206 },
207 Error::Other(msg) => CoreError::Other {
208 context: "primitives",
209 #[cfg(feature = "std")]
210 message: msg.to_string(),
211 },
212 }
213 }
214}
215
216#[inline]
218pub fn to_core_result<T>(r: Result<T>, ctx: &'static str) -> CoreResult<T> {
219 r.map_err(|e| {
220 let mut core = CoreError::from(e);
221 core = core.with_context(ctx);
222 core
223 })
224}
225
226pub use dcrypt_api::error::{ResultExt, SecureErrorHandling};
228
229pub mod validate;