Skip to main content

ntex_error/
utils.rs

1use std::{convert::Infallible, error::Error as StdError, fmt, io};
2
3use crate::{Error, ErrorDiagnostic, ResultType};
4
5impl ErrorDiagnostic for Infallible {
6    type Kind = ResultType;
7
8    fn kind(&self) -> Self::Kind {
9        unreachable!()
10    }
11}
12
13impl ErrorDiagnostic for io::Error {
14    type Kind = ResultType;
15
16    fn kind(&self) -> Self::Kind {
17        match self.kind() {
18            io::ErrorKind::InvalidData
19            | io::ErrorKind::Unsupported
20            | io::ErrorKind::UnexpectedEof
21            | io::ErrorKind::BrokenPipe
22            | io::ErrorKind::ConnectionReset
23            | io::ErrorKind::ConnectionAborted
24            | io::ErrorKind::NotConnected
25            | io::ErrorKind::TimedOut => ResultType::ClientError,
26            _ => ResultType::ServiceError,
27        }
28    }
29}
30
31#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
32pub struct Success;
33
34impl StdError for Success {}
35
36impl ErrorDiagnostic for Success {
37    type Kind = ResultType;
38
39    fn kind(&self) -> Self::Kind {
40        ResultType::Success
41    }
42}
43
44impl fmt::Display for Success {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
46        write!(f, "Success")
47    }
48}
49
50/// Execute future and set error service.
51///
52/// Sets service if it not set
53pub async fn with_service<F, T, E>(svc: &'static str, fut: F) -> F::Output
54where
55    F: Future<Output = Result<T, Error<E>>>,
56    E: ErrorDiagnostic + Clone,
57{
58    fut.await.map_err(|err: Error<E>| {
59        if err.service().is_none() {
60            err.set_service(svc)
61        } else {
62            err
63        }
64    })
65}