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
50pub 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}