wireman_core/client/
mod.rs1#![allow(clippy::module_name_repetitions)]
2pub(crate) mod codec;
3pub mod reflection;
4pub mod tls;
5
6use crate::descriptor::response::StreamingResponse;
7use crate::descriptor::RequestMessage;
8use crate::descriptor::ResponseMessage;
9use crate::error::Error;
10use crate::Result;
11use tls::TlsConfig;
12use tonic::transport::Uri;
13use tonic::{client::Grpc, transport::Channel};
14
15#[derive(Clone, Debug)]
17pub struct GrpcClient {
18 grpc: Grpc<Channel>,
19}
20
21impl GrpcClient {
22 pub fn new<T: Into<Uri>>(uri: T, tls_config: Option<TlsConfig>) -> Result<Self> {
29 let builder = Channel::builder(uri.into());
30
31 let channel = if let Some(tls_config) = tls_config {
32 builder.tls_config(tls_config.0)?.connect_lazy()
33 } else {
34 builder.connect_lazy()
35 };
36
37 Ok(GrpcClient {
38 grpc: Grpc::new(channel),
39 })
40 }
41
42 pub async fn unary(&mut self, request: &RequestMessage) -> Result<ResponseMessage> {
48 self.grpc.ready().await.map_err(Error::GrpcNotReady)?;
49
50 let path = request.path();
51 let codec = request.codec();
52
53 let request = request.clone().into();
54 let response = self.grpc.unary(request, path, codec).await?;
55
56 Ok(response.into_inner())
57 }
58
59 pub async fn server_streaming(
65 &mut self,
66 request: &RequestMessage,
67 ) -> Result<StreamingResponse> {
68 self.grpc.ready().await.map_err(Error::GrpcNotReady)?;
69
70 let path = request.path();
71 let codec = request.codec();
72
73 let request = request.clone().into();
74 let response = self.grpc.server_streaming(request, path, codec).await?;
75
76 Ok(StreamingResponse::new(response.into_inner()))
77 }
78
79 pub async fn client_streaming<S>(
85 &mut self,
86 head: &RequestMessage,
87 messages: S,
88 ) -> Result<ResponseMessage>
89 where
90 S: tokio_stream::Stream<Item = RequestMessage> + Send + 'static,
91 {
92 self.grpc.ready().await.map_err(Error::GrpcNotReady)?;
93
94 let path = head.path();
95 let codec = head.codec();
96
97 let request = into_streaming_request(head, messages);
98 let response = self.grpc.client_streaming(request, path, codec).await?;
99
100 Ok(response.into_inner())
101 }
102
103 pub async fn bidirectional_streaming<S>(
109 &mut self,
110 head: &RequestMessage,
111 messages: S,
112 ) -> Result<StreamingResponse>
113 where
114 S: tokio_stream::Stream<Item = RequestMessage> + Send + 'static,
115 {
116 self.grpc.ready().await.map_err(Error::GrpcNotReady)?;
117
118 let path = head.path();
119 let codec = head.codec();
120
121 let request = into_streaming_request(head, messages);
122 let response = self.grpc.streaming(request, path, codec).await?;
123
124 Ok(StreamingResponse::new(response.into_inner()))
125 }
126}
127
128fn into_streaming_request<S>(head: &RequestMessage, messages: S) -> tonic::Request<S>
131where
132 S: tokio_stream::Stream<Item = RequestMessage>,
133{
134 let metadata = head.metadata().clone();
135 let mut req = tonic::Request::new(messages);
136 if let Some(metadata) = metadata {
137 *req.metadata_mut() = metadata.inner;
138 }
139 req
140}
141
142pub async fn call_unary_async(
148 request: &RequestMessage,
149 tls: Option<TlsConfig>,
150) -> Result<ResponseMessage> {
151 let uri = request.uri()?;
152
153 let mut client = GrpcClient::new(uri, tls)?;
154
155 client.unary(request).await
156}
157
158pub async fn call_server_streaming(
164 req: &RequestMessage,
165 tls: Option<TlsConfig>,
166) -> Result<StreamingResponse> {
167 let uri = req.uri()?;
168
169 let mut client = GrpcClient::new(uri, tls)?;
170
171 client.server_streaming(req).await
172}
173
174pub async fn call_client_streaming<S>(
180 head: &RequestMessage,
181 messages: S,
182 tls: Option<TlsConfig>,
183) -> Result<ResponseMessage>
184where
185 S: tokio_stream::Stream<Item = RequestMessage> + Send + 'static,
186{
187 let uri = head.uri()?;
188
189 let mut client = GrpcClient::new(uri, tls)?;
190
191 client.client_streaming(head, messages).await
192}
193
194pub async fn call_bidirectional_streaming<S>(
200 head: &RequestMessage,
201 messages: S,
202 tls: Option<TlsConfig>,
203) -> Result<StreamingResponse>
204where
205 S: tokio_stream::Stream<Item = RequestMessage> + Send + 'static,
206{
207 let uri = head.uri()?;
208
209 let mut client = GrpcClient::new(uri, tls)?;
210
211 client.bidirectional_streaming(head, messages).await
212}