1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::{
convert::Infallible,
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use futures_util::{Sink, Stream};
use crate::{
common::socket::{BoxedSocketRx, BoxedSocketTx, SocketMessage},
BoxError, Request,
};
use super::error::ClientError;
#[cfg(feature = "_common_http_client")]
pub mod http;
#[cfg(feature = "mock_client")]
pub mod mock;
#[derive(Debug)]
pub enum TransportError<Err> {
Transport(Err),
GenericClient(ClientError<Infallible>),
}
impl<Err> From<TransportError<Err>> for ClientError<Err> {
fn from(err: TransportError<Err>) -> Self {
match err {
TransportError::Transport(err) => ClientError::Transport(err),
TransportError::GenericClient(err) => match err {
ClientError::ContentNotSupported => ClientError::ContentNotSupported,
ClientError::EndpointError {
hrpc_error,
endpoint,
} => ClientError::EndpointError {
hrpc_error,
endpoint,
},
ClientError::IncompatibleSpecVersion => ClientError::IncompatibleSpecVersion,
ClientError::MessageDecode(err) => ClientError::MessageDecode(err),
ClientError::Transport(_) => unreachable!("infallible"),
},
}
}
}
impl<Err> From<ClientError<Err>> for TransportError<Err> {
fn from(err: ClientError<Err>) -> Self {
match err {
ClientError::Transport(err) => TransportError::Transport(err),
other => TransportError::GenericClient(match other {
ClientError::ContentNotSupported => ClientError::ContentNotSupported,
ClientError::EndpointError {
hrpc_error,
endpoint,
} => ClientError::EndpointError {
hrpc_error,
endpoint,
},
ClientError::IncompatibleSpecVersion => ClientError::IncompatibleSpecVersion,
ClientError::MessageDecode(err) => ClientError::MessageDecode(err),
ClientError::Transport(_) => unreachable!("infallible"),
}),
}
}
}
impl<Err: Display> Display for TransportError<Err> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
TransportError::Transport(err) => write!(f, "transport error: {}", err),
TransportError::GenericClient(err) => write!(f, "{}", err),
}
}
}
impl<Err: StdError + 'static> StdError for TransportError<Err> {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
TransportError::GenericClient(err) => Some(err),
TransportError::Transport(err) => Some(err),
}
}
}
pub struct SocketChannels {
pub(super) tx: BoxedSocketTx,
pub(super) rx: BoxedSocketRx,
}
impl SocketChannels {
pub fn new<Tx, Rx>(tx: Tx, rx: Rx) -> Self
where
Tx: Sink<SocketMessage, Error = BoxError> + Send + Sync + 'static,
Rx: Stream<Item = Result<SocketMessage, BoxError>> + Send + Sync + 'static,
{
Self {
tx: Box::pin(tx),
rx: Box::pin(rx),
}
}
}
pub(super) struct SocketRequestMarker;
pub fn is_socket_request<T>(req: &Request<T>) -> bool {
req.extensions().contains::<SocketRequestMarker>()
}