1use std::fmt;
2
3pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
5
6pub type Result<T> = std::result::Result<T, BoxError>;
8
9#[derive(Debug, Default, Copy, Clone)]
11pub struct BadVersion;
12
13impl fmt::Display for BadVersion {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 f.pad("Unknown HTTP version")
16 }
17}
18
19impl std::error::Error for BadVersion {}
20
21#[derive(Debug, Default, Copy, Clone)]
23pub struct BadHeader;
24
25impl fmt::Display for BadHeader {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.pad("Error parsing header value")
28 }
29}
30
31impl std::error::Error for BadHeader {}
32
33#[derive(Debug, Default, Copy, Clone)]
35pub struct BadRequest;
36
37impl fmt::Display for BadRequest {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 f.pad("Request object is not cloneable. Are you passing a streaming body?")
40 }
41}
42
43impl std::error::Error for BadRequest {}
44
45#[derive(Debug)]
68pub enum HttpCacheError {
69 Client(BoxError),
71 Cache(String),
73 BadRequest(BadRequest),
75 Http(BoxError),
77 Body(BoxError),
79 Streaming(StreamingError),
81 Other(BoxError),
83}
84
85impl HttpCacheError {
86 pub fn cache<S: Into<String>>(message: S) -> Self {
96 Self::Cache(message.into())
97 }
98
99 pub fn http<E: Into<BoxError>>(error: E) -> Self {
109 Self::Http(error.into())
110 }
111
112 pub fn body<E: Into<BoxError>>(error: E) -> Self {
122 Self::Body(error.into())
123 }
124
125 pub fn client<E: Into<BoxError>>(error: E) -> Self {
135 Self::Client(error.into())
136 }
137
138 pub fn other<E: Into<BoxError>>(error: E) -> Self {
148 Self::Other(error.into())
149 }
150
151 pub fn is_cache_error(&self) -> bool {
153 matches!(self, Self::Cache(_))
154 }
155
156 pub fn is_client_error(&self) -> bool {
158 matches!(self, Self::Client(_))
159 }
160
161 pub fn is_streaming_error(&self) -> bool {
163 matches!(self, Self::Streaming(_))
164 }
165
166 pub fn is_bad_request(&self) -> bool {
168 matches!(self, Self::BadRequest(_))
169 }
170}
171
172impl fmt::Display for HttpCacheError {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 match self {
175 Self::Client(e) => write!(f, "HTTP client error: {e}"),
176 Self::Cache(msg) => write!(f, "Cache error: {msg}"),
177 Self::BadRequest(e) => write!(f, "Request error: {e}"),
178 Self::Http(e) => write!(f, "HTTP error: {e}"),
179 Self::Body(e) => write!(f, "Body processing error: {e}"),
180 Self::Streaming(e) => write!(f, "Streaming error: {e}"),
181 Self::Other(e) => write!(f, "Other error: {e}"),
182 }
183 }
184}
185
186impl std::error::Error for HttpCacheError {
187 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
188 match self {
189 Self::Client(e) => Some(e.as_ref()),
190 Self::Cache(_) => None,
191 Self::BadRequest(e) => Some(e),
192 Self::Http(e) => Some(e.as_ref()),
193 Self::Body(e) => Some(e.as_ref()),
194 Self::Streaming(e) => Some(e),
195 Self::Other(e) => Some(e.as_ref()),
196 }
197 }
198}
199
200impl From<BadRequest> for HttpCacheError {
203 fn from(error: BadRequest) -> Self {
204 Self::BadRequest(error)
205 }
206}
207
208impl From<BadHeader> for HttpCacheError {
209 fn from(error: BadHeader) -> Self {
210 Self::Http(Box::new(error))
211 }
212}
213
214impl From<BadVersion> for HttpCacheError {
215 fn from(error: BadVersion) -> Self {
216 Self::Http(Box::new(error))
217 }
218}
219
220impl From<StreamingError> for HttpCacheError {
221 fn from(error: StreamingError) -> Self {
222 Self::Streaming(error)
223 }
224}
225
226impl From<BoxError> for HttpCacheError {
227 fn from(error: BoxError) -> Self {
228 Self::Other(error)
229 }
230}
231
232impl From<std::io::Error> for HttpCacheError {
233 fn from(error: std::io::Error) -> Self {
234 Self::Other(Box::new(error))
235 }
236}
237
238impl From<http::Error> for HttpCacheError {
239 fn from(error: http::Error) -> Self {
240 Self::Http(Box::new(error))
241 }
242}
243
244impl From<http::header::InvalidHeaderValue> for HttpCacheError {
245 fn from(error: http::header::InvalidHeaderValue) -> Self {
246 Self::Http(Box::new(error))
247 }
248}
249
250impl From<http::header::InvalidHeaderName> for HttpCacheError {
251 fn from(error: http::header::InvalidHeaderName) -> Self {
252 Self::Http(Box::new(error))
253 }
254}
255
256impl From<http::uri::InvalidUri> for HttpCacheError {
257 fn from(error: http::uri::InvalidUri) -> Self {
258 Self::Http(Box::new(error))
259 }
260}
261
262impl From<http::method::InvalidMethod> for HttpCacheError {
263 fn from(error: http::method::InvalidMethod) -> Self {
264 Self::Http(Box::new(error))
265 }
266}
267
268impl From<http::status::InvalidStatusCode> for HttpCacheError {
269 fn from(error: http::status::InvalidStatusCode) -> Self {
270 Self::Http(Box::new(error))
271 }
272}
273
274impl From<url::ParseError> for HttpCacheError {
275 fn from(error: url::ParseError) -> Self {
276 Self::Http(Box::new(error))
277 }
278}
279
280pub type HttpCacheResult<T> = std::result::Result<T, HttpCacheError>;
287
288#[derive(Debug)]
290pub struct StreamingError {
291 inner: BoxError,
292 kind: StreamingErrorKind,
293}
294
295#[derive(Debug, Clone, Copy)]
297pub enum StreamingErrorKind {
298 Io,
300 Serialization,
302 Concurrency,
304 Consistency,
306 TempFile,
308 ContentAddressing,
310 Client,
312 Other,
314}
315
316impl StreamingError {
317 pub fn new<E: Into<BoxError>>(error: E) -> Self {
319 Self { inner: error.into(), kind: StreamingErrorKind::Other }
320 }
321
322 pub fn with_kind<E: Into<BoxError>>(
324 error: E,
325 kind: StreamingErrorKind,
326 ) -> Self {
327 Self { inner: error.into(), kind }
328 }
329
330 pub fn io<E: Into<BoxError>>(error: E) -> Self {
332 Self::with_kind(error, StreamingErrorKind::Io)
333 }
334
335 pub fn serialization<E: Into<BoxError>>(error: E) -> Self {
337 Self::with_kind(error, StreamingErrorKind::Serialization)
338 }
339
340 pub fn concurrency<E: Into<BoxError>>(error: E) -> Self {
342 Self::with_kind(error, StreamingErrorKind::Concurrency)
343 }
344
345 pub fn consistency<E: Into<BoxError>>(error: E) -> Self {
347 Self::with_kind(error, StreamingErrorKind::Consistency)
348 }
349
350 pub fn temp_file<E: Into<BoxError>>(error: E) -> Self {
352 Self::with_kind(error, StreamingErrorKind::TempFile)
353 }
354
355 pub fn content_addressing<E: Into<BoxError>>(error: E) -> Self {
357 Self::with_kind(error, StreamingErrorKind::ContentAddressing)
358 }
359
360 pub fn client<E: Into<BoxError>>(error: E) -> Self {
362 Self::with_kind(error, StreamingErrorKind::Client)
363 }
364
365 pub fn kind(&self) -> &StreamingErrorKind {
367 &self.kind
368 }
369}
370
371impl fmt::Display for StreamingError {
372 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373 write!(f, "Streaming error: {}", self.inner)
374 }
375}
376
377impl std::error::Error for StreamingError {
378 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
379 Some(&*self.inner)
380 }
381}
382
383impl From<BoxError> for StreamingError {
384 fn from(error: BoxError) -> Self {
385 Self::new(error)
386 }
387}
388
389impl From<std::convert::Infallible> for StreamingError {
390 fn from(never: std::convert::Infallible) -> Self {
391 match never {}
392 }
393}
394
395impl From<std::io::Error> for StreamingError {
396 fn from(error: std::io::Error) -> Self {
397 Self::new(error)
398 }
399}
400
401impl From<HttpCacheError> for StreamingError {
402 fn from(error: HttpCacheError) -> Self {
403 match error {
404 HttpCacheError::Streaming(streaming_err) => streaming_err,
405 _ => Self::new(Box::new(error)),
406 }
407 }
408}
409
410#[derive(Debug)]
425pub enum ClientStreamingError {
426 Client {
428 client: String,
430 error: BoxError,
432 },
433 HttpCache(StreamingError),
435 Other(BoxError),
437}
438
439impl ClientStreamingError {
440 pub fn client<C, E>(client: C, error: E) -> Self
450 where
451 C: Into<String>,
452 E: Into<BoxError>,
453 {
454 Self::Client { client: client.into(), error: error.into() }
455 }
456
457 pub fn http_cache(error: StreamingError) -> Self {
468 Self::HttpCache(error)
469 }
470
471 pub fn other<E: Into<BoxError>>(error: E) -> Self {
481 Self::Other(error.into())
482 }
483}
484
485impl fmt::Display for ClientStreamingError {
486 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
487 match self {
488 Self::Client { client, error } => {
489 write!(f, "{} streaming error: {}", client, error)
490 }
491 Self::HttpCache(e) => {
492 write!(f, "HTTP cache streaming error: {}", e)
493 }
494 Self::Other(e) => write!(f, "Streaming error: {}", e),
495 }
496 }
497}
498
499impl std::error::Error for ClientStreamingError {
500 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
501 match self {
502 Self::Client { error, .. } => Some(error.as_ref()),
503 Self::HttpCache(e) => Some(e),
504 Self::Other(e) => Some(e.as_ref()),
505 }
506 }
507}
508
509impl From<StreamingError> for ClientStreamingError {
510 fn from(error: StreamingError) -> Self {
511 Self::HttpCache(error)
512 }
513}
514
515impl From<BoxError> for ClientStreamingError {
516 fn from(error: BoxError) -> Self {
517 Self::Other(error)
518 }
519}
520
521impl From<ClientStreamingError> for HttpCacheError {
522 fn from(error: ClientStreamingError) -> Self {
523 match error {
524 ClientStreamingError::HttpCache(streaming_err) => {
525 Self::Streaming(streaming_err)
526 }
527 ClientStreamingError::Client { error, .. } => Self::Client(error),
528 ClientStreamingError::Other(error) => Self::Other(error),
529 }
530 }
531}
532
533impl From<ClientStreamingError> for StreamingError {
534 fn from(error: ClientStreamingError) -> Self {
535 match error {
536 ClientStreamingError::HttpCache(streaming_err) => streaming_err,
537 ClientStreamingError::Client { client, error } => {
538 let client_error =
540 format!("Client '{}' error: {}", client, error);
541 Self::client(client_error)
542 }
543 ClientStreamingError::Other(error) => Self::new(error),
544 }
545 }
546}