Skip to content

Commit 49a738d

Browse files
committed
second attempt
1 parent 05e4f6a commit 49a738d

File tree

4 files changed

+50
-46
lines changed

4 files changed

+50
-46
lines changed

crates/twirp-build/src/lib.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
166166
let mut client_methods = Vec::with_capacity(service.methods.len());
167167
for m in &service.methods {
168168
let name = &m.name;
169-
let build_name = format_ident!("build_{}", name);
169+
let name_request = format_ident!("{}_request", name);
170170
let input_type = &m.input_type;
171171
let output_type = &m.output_type;
172172
let request_path = format!("{}/{}", service.fqn, m.proto_name);
@@ -175,18 +175,17 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
175175
async fn #name(&self, req: #input_type) -> Result<#output_type, twirp::ClientError>;
176176
});
177177
client_trait_methods.push(quote! {
178-
fn #build_name(&self, req: #input_type) -> Result<twirp::RequestBuilder<#input_type, #output_type>, twirp::ClientError>;
178+
fn #name_request(&self, req: #input_type) -> Result<twirp::RequestBuilder<#input_type, #output_type>, twirp::ClientError>;
179179
});
180180

181181
client_methods.push(quote! {
182-
fn #build_name(&self, req: #input_type) -> Result<twirp::RequestBuilder<#input_type, #output_type>, twirp::ClientError> {
183-
self.build_request(#request_path, req)
182+
fn #name_request(&self, req: #input_type) -> Result<twirp::RequestBuilder<#input_type, #output_type>, twirp::ClientError> {
183+
self.request(#request_path, req)
184184
}
185185
});
186186
client_methods.push(quote! {
187187
async fn #name(&self, req: #input_type) -> Result<#output_type, twirp::ClientError> {
188-
let builder = self.#build_name(req)?;
189-
self.request(builder).await
188+
self.#name_request(req)?.send().await
190189
}
191190
});
192191
}

crates/twirp/src/client.rs

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -158,31 +158,10 @@ impl Client {
158158
}
159159
}
160160

161-
pub fn build_request<I, O>(&self, path: &str, body: I) -> Result<RequestBuilder<I, O>>
161+
pub(super) async fn execute<O>(&self, req: reqwest::Request) -> Result<O>
162162
where
163-
I: prost::Message,
164163
O: prost::Message + Default,
165164
{
166-
let mut url = self.inner.base_url.join(path)?;
167-
if let Some(host) = &self.host {
168-
url.set_host(Some(host))?
169-
};
170-
171-
let req = self
172-
.http_client
173-
.post(url)
174-
.header(CONTENT_TYPE, CONTENT_TYPE_PROTOBUF)
175-
.body(serialize_proto_message(body));
176-
Ok(RequestBuilder::new(req))
177-
}
178-
179-
/// Make an HTTP twirp request.
180-
pub async fn request<I, O>(&self, builder: RequestBuilder<I, O>) -> Result<O>
181-
where
182-
I: prost::Message,
183-
O: prost::Message + Default,
184-
{
185-
let req = builder.build()?;
186165
let path = req.url().path().to_string();
187166

188167
// Create and execute the middleware handlers
@@ -216,36 +195,64 @@ impl Client {
216195
}),
217196
}
218197
}
198+
199+
// Start building a request...
200+
pub fn request<I, O>(&self, path: &str, body: I) -> Result<RequestBuilder<I, O>>
201+
where
202+
I: prost::Message,
203+
O: prost::Message + Default,
204+
{
205+
let mut url = self.inner.base_url.join(path)?;
206+
if let Some(host) = &self.host {
207+
url.set_host(Some(host))?
208+
};
209+
210+
let req = self
211+
.http_client
212+
.post(url)
213+
.header(CONTENT_TYPE, CONTENT_TYPE_PROTOBUF)
214+
.body(serialize_proto_message(body));
215+
Ok(RequestBuilder::new(self.clone(), req))
216+
}
219217
}
220218

221-
pub struct RequestBuilder<I, O> {
219+
pub struct RequestBuilder<I, O>
220+
where
221+
O: prost::Message + Default,
222+
{
223+
client: Client,
222224
inner: reqwest::RequestBuilder,
223225
_input: std::marker::PhantomData<I>,
224226
_output: std::marker::PhantomData<O>,
225227
}
226228

227-
impl<I, O> RequestBuilder<I, O> {
228-
pub fn new(inner: reqwest::RequestBuilder) -> Self {
229+
impl<I, O> RequestBuilder<I, O>
230+
where
231+
O: prost::Message + Default,
232+
{
233+
pub fn new(client: Client, inner: reqwest::RequestBuilder) -> Self {
229234
Self {
235+
client,
230236
inner,
231237
_input: std::marker::PhantomData,
232238
_output: std::marker::PhantomData,
233239
}
234240
}
235241

236-
pub fn header<K, V>(self, key: K, value: V) -> RequestBuilder<I, O>
242+
pub fn header<K, V>(mut self, key: K, value: V) -> RequestBuilder<I, O>
237243
where
238244
HeaderName: TryFrom<K>,
239245
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
240246
HeaderValue: TryFrom<V>,
241247
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
242248
{
243-
RequestBuilder::new(self.inner.header(key, value))
249+
self.inner = self.inner.header(key, value);
250+
self
244251
}
245252

246-
/// Builds the request.
247-
pub fn build(self) -> Result<reqwest::Request, reqwest::Error> {
248-
self.inner.build()
253+
pub async fn send(self) -> Result<O> {
254+
let req = self.inner.build()?;
255+
self.client.execute(req).await
249256
}
250257
}
251258

crates/twirp/src/test.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ pub trait TestApiClient {
121121
#[async_trait]
122122
impl TestApiClient for Client {
123123
async fn ping(&self, req: PingRequest) -> Result<PingResponse> {
124-
let req = self.build_request("test.TestAPI/Ping", req)?;
125-
self.request(req).await
124+
self.request("test.TestAPI/Ping", req)?.send().await
126125
}
127126

128127
async fn boom(&self, _req: PingRequest) -> Result<PingResponse> {

example/src/bin/client.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ pub async fn main() -> Result<(), GenericError> {
3838
.await;
3939
eprintln!("{:?}", resp);
4040

41-
// TODO: Figure out where `with_host` goes in all this...
42-
let req = client
41+
let resp = client
4342
.with_host("localhost")
44-
.build_make_hat(MakeHatRequest { inches: 1 })?
45-
.header("x-custom-header", "a");
46-
// Make a request with context
47-
let resp = client.request(req).await?;
43+
.make_hat_request(MakeHatRequest { inches: 1 })?
44+
.header("x-custom-header", "a")
45+
.send()
46+
.await?;
4847
eprintln!("{:?}", resp);
4948

5049
Ok(())
@@ -88,7 +87,7 @@ struct MockHaberdasherApiClient;
8887

8988
#[async_trait]
9089
impl HaberdasherApiClient for MockHaberdasherApiClient {
91-
fn build_make_hat(
90+
fn make_hat_request(
9291
&self,
9392
_req: MakeHatRequest,
9493
) -> Result<twirp::RequestBuilder<MakeHatRequest, MakeHatResponse>, twirp::ClientError> {
@@ -98,7 +97,7 @@ impl HaberdasherApiClient for MockHaberdasherApiClient {
9897
todo!()
9998
}
10099

101-
fn build_get_status(
100+
fn get_status_request(
102101
&self,
103102
_req: GetStatusRequest,
104103
) -> Result<twirp::RequestBuilder<GetStatusRequest, GetStatusResponse>, twirp::ClientError>

0 commit comments

Comments
 (0)