Skip to content

Commit 370a614

Browse files
committed
Support asynchronous clients
Thanks to async/await the implementation and API of async clients is pretty close to the API of the sync clients! This means that almost all of the codegen is shared, with a flag passed around to make the few changes we need here and there.
1 parent c6d997a commit 370a614

File tree

12 files changed

+1650
-173
lines changed

12 files changed

+1650
-173
lines changed

Cargo.lock

Lines changed: 190 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-codegen/src/clients.rs

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,40 @@ use crate::types::{
1919
ArgumentDefinition, AuthType, EndpointDefinition, ParameterType, ServiceDefinition, Type,
2020
};
2121

22+
#[derive(Copy, Clone)]
23+
enum Style {
24+
Async,
25+
Sync,
26+
}
27+
2228
pub fn generate(ctx: &Context, def: &ServiceDefinition) -> TokenStream {
29+
let async_ = generate_inner(ctx, def, Style::Async);
30+
let sync = generate_inner(ctx, def, Style::Sync);
31+
32+
quote! {
33+
#async_
34+
35+
#sync
36+
}
37+
}
38+
39+
fn generate_inner(ctx: &Context, def: &ServiceDefinition, style: Style) -> TokenStream {
2340
let docs = ctx.docs(def.docs());
24-
let name = ctx.type_name(&format!("{}Client", def.service_name().name()));
41+
let suffix = match style {
42+
Style::Async => "AsyncClient",
43+
Style::Sync => "Client",
44+
};
45+
let name = ctx.type_name(&format!("{}{}", def.service_name().name(), suffix));
46+
47+
let client_bound = match style {
48+
Style::Async => quote!(AsyncClient),
49+
Style::Sync => quote!(Client),
50+
};
2551

2652
let endpoints = def
2753
.endpoints()
2854
.iter()
29-
.map(|e| generate_endpoint(ctx, def, e));
55+
.map(|e| generate_endpoint(ctx, def, style, e));
3056

3157
quote! {
3258
#docs
@@ -35,7 +61,7 @@ pub fn generate(ctx: &Context, def: &ServiceDefinition) -> TokenStream {
3561

3662
impl<T> #name<T>
3763
where
38-
T: conjure_http::client::Client
64+
T: conjure_http::client::#client_bound,
3965
{
4066
/// Creates a new client.
4167
#[inline]
@@ -51,6 +77,7 @@ pub fn generate(ctx: &Context, def: &ServiceDefinition) -> TokenStream {
5177
fn generate_endpoint(
5278
ctx: &Context,
5379
def: &ServiceDefinition,
80+
style: Style,
5481
endpoint: &EndpointDefinition,
5582
) -> TokenStream {
5683
let docs = ctx.docs(endpoint.docs());
@@ -63,6 +90,12 @@ fn generate_endpoint(
6390
}
6491
None => quote!(),
6592
};
93+
94+
let async_ = match style {
95+
Style::Async => quote!(async),
96+
Style::Sync => quote!(),
97+
};
98+
6699
let name = ctx.field_name(endpoint.endpoint_name());
67100

68101
let body_arg = body_arg(endpoint);
@@ -79,7 +112,7 @@ fn generate_endpoint(
79112
let result = ctx.result_ident(def.service_name());
80113
let ret = return_type(ctx, endpoint);
81114
let ret_name = return_type_name(ctx, def, &ret);
82-
let where_ = where_(ctx, body_arg);
115+
let where_ = where_(ctx, style, body_arg);
83116

84117
let method = endpoint
85118
.http_method()
@@ -104,10 +137,15 @@ fn generate_endpoint(
104137
let response_visitor = quote!(response_visitor_);
105138
let setup_response_visitor = setup_response_visitor(ctx, &ret, &response_visitor);
106139

140+
let await_ = match style {
141+
Style::Async => quote!(.await),
142+
Style::Sync => quote!(),
143+
};
144+
107145
quote! {
108146
#docs
109147
#deprecated
110-
pub fn #name #params(&self #auth_arg #(, #args)*) -> #result<#ret_name, conjure_http::private::Error>
148+
pub #async_ fn #name #params(&self #auth_arg #(, #args)*) -> #result<#ret_name, conjure_http::private::Error>
111149
#where_
112150
{
113151
#setup_path_params
@@ -125,6 +163,7 @@ fn generate_endpoint(
125163
#body,
126164
#response_visitor,
127165
)
166+
#await_
128167
}
129168
}
130169
}
@@ -143,10 +182,16 @@ fn params(ctx: &Context, body_arg: Option<&ArgumentDefinition>) -> TokenStream {
143182
}
144183
}
145184

146-
fn where_(ctx: &Context, body_arg: Option<&ArgumentDefinition>) -> TokenStream {
185+
fn where_(ctx: &Context, style: Style, body_arg: Option<&ArgumentDefinition>) -> TokenStream {
147186
match body_arg {
148187
Some(a) if ctx.is_binary(a.type_()) => {
149-
quote!(where U: conjure_http::client::WriteBody<T::BinaryWriter>)
188+
let bound = match style {
189+
Style::Async => {
190+
quote!(conjure_http::client::AsyncWriteBody<T::BinaryWriter> + Sync + Send)
191+
}
192+
Style::Sync => quote!(conjure_http::client::WriteBody<T::BinaryWriter>),
193+
};
194+
quote!(where U: #bound,)
150195
}
151196
_ => quote!(),
152197
}

conjure-codegen/src/example_types/another/mod.rs

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)