Skip to content

Commit 76d5c2e

Browse files
authored
Pass reference to Elasticsearch struct to builder structs (#38)
This commit changes the api_generator to pass a reference to an instance of Elasticsearch struct to each builder struct. The reference has a lifetime of 'a, distinct from the lifetime 'b of the *Parts enum and references passed to builder struct functions. Closes #36
1 parent 41e3a5f commit 76d5c2e

File tree

25 files changed

+5968
-5852
lines changed

25 files changed

+5968
-5852
lines changed

api_generator/src/api_generator/code_gen/mod.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ fn typekind_to_ty(name: &str, kind: TypeKind, required: bool) -> syn::Ty {
126126
v.push_str("Option<");
127127
}
128128

129-
let str_type = "&'a str";
129+
let str_type = "&'b str";
130130
match kind {
131131
TypeKind::None => v.push_str(str_type),
132-
TypeKind::List => v.push_str(format!("&'a [{}]", str_type).as_ref()),
132+
TypeKind::List => v.push_str(format!("&'b [{}]", str_type).as_ref()),
133133
TypeKind::Enum => v.push_str(name.to_pascal_case().as_str()),
134134
TypeKind::String => v.push_str(str_type),
135135
TypeKind::Text => v.push_str(str_type),
@@ -150,10 +150,10 @@ fn typekind_to_ty(name: &str, kind: TypeKind, required: bool) -> syn::Ty {
150150
syn::parse_type(v.as_str()).unwrap()
151151
}
152152

153-
/// A standard `'a` lifetime
154-
pub fn lifetime_a() -> syn::Lifetime {
153+
/// A standard `'b` lifetime
154+
pub fn lifetime_b() -> syn::Lifetime {
155155
syn::Lifetime {
156-
ident: syn::Ident::new("'a"),
156+
ident: syn::Ident::new("'b"),
157157
}
158158
}
159159

@@ -170,9 +170,9 @@ impl<T: GetPath> HasLifetime for T {
170170
}
171171
}
172172

173-
/// Generics with a standard `'a` lifetime
174-
pub fn generics_a() -> syn::Generics {
175-
generics(vec![lifetime_a()], vec![])
173+
/// Generics with a standard `'b` lifetime
174+
pub fn generics_b() -> syn::Generics {
175+
generics(vec![lifetime_b()], vec![])
176176
}
177177

178178
/// Generics with no parameters.
@@ -201,9 +201,9 @@ pub fn ty_path(ty: &str, lifetimes: Vec<syn::Lifetime>, types: Vec<syn::Ty>) ->
201201
syn::Ty::Path(None, path(ty, lifetimes, types))
202202
}
203203

204-
/// AST for a path type with a `'a` lifetime.
205-
pub fn ty_a(ty: &str) -> syn::Ty {
206-
ty_path(ty, vec![lifetime_a()], vec![])
204+
/// AST for a path type with a `'b` lifetime.
205+
pub fn ty_b(ty: &str) -> syn::Ty {
206+
ty_path(ty, vec![lifetime_b()], vec![])
207207
}
208208

209209
/// AST for a simple path type.

api_generator/src/api_generator/code_gen/namespace_clients.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ pub fn generate(api: &Api) -> Result<Vec<(String, String)>, failure::Error> {
4949
#(#builders)*
5050

5151
#namespace_doc
52-
pub struct #namespace_client_name {
53-
client: Elasticsearch
52+
pub struct #namespace_client_name<'a> {
53+
client: &'a Elasticsearch
5454
}
5555

56-
impl #namespace_client_name {
56+
impl<'a> #namespace_client_name<'a> {
5757
#new_namespace_client_doc
58-
pub fn new(client: Elasticsearch) -> Self {
58+
pub fn new(client: &'a Elasticsearch) -> Self {
5959
Self {
6060
client
6161
}
@@ -66,7 +66,7 @@ pub fn generate(api: &Api) -> Result<Vec<(String, String)>, failure::Error> {
6666
impl Elasticsearch {
6767
#namespace_fn_doc
6868
pub fn #namespace_name(&self) -> #namespace_client_name {
69-
#namespace_client_name::new(self.clone())
69+
#namespace_client_name::new(&self)
7070
}
7171
}
7272
));

api_generator/src/api_generator/code_gen/request/request_builder.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl<'a> RequestBuilder<'a> {
130130
{
131131
#[serde_with::skip_serializing_none]
132132
#[derive(Serialize)]
133-
struct #query_struct_ty<'a> {
133+
struct #query_struct_ty<'b> {
134134
#(#struct_fields,)*
135135
}
136136
let query_params = #query_struct_ty {
@@ -155,7 +155,7 @@ impl<'a> RequestBuilder<'a> {
155155
let doc = doc(format!("Creates a new instance of [{}]", &builder_name));
156156
quote!(
157157
#doc
158-
pub fn new(client: Elasticsearch) -> Self {
158+
pub fn new(client: &'a Elasticsearch) -> Self {
159159
#builder_ident {
160160
client,
161161
parts: #enum_ty::None,
@@ -171,7 +171,7 @@ impl<'a> RequestBuilder<'a> {
171171
));
172172
quote!(
173173
#doc
174-
pub fn new(client: Elasticsearch, parts: #enum_ty) -> Self {
174+
pub fn new(client: &'a Elasticsearch, parts: #enum_ty) -> Self {
175175
#builder_ident {
176176
client,
177177
parts,
@@ -210,15 +210,15 @@ impl<'a> RequestBuilder<'a> {
210210
syn::parse_type("Vec<T>").unwrap(),
211211
quote!(Some(NdBody(body))),
212212
syn::FunctionRetTy::Ty(code_gen::ty(
213-
format!("{}<'a, NdBody<T>> where T: Body", &builder_name).as_ref(),
213+
format!("{}<'a, 'b, NdBody<T>> where T: Body", &builder_name).as_ref(),
214214
)),
215215
)
216216
} else {
217217
(
218218
syn::parse_type("T").unwrap(),
219219
quote!(Some(body.into())),
220220
syn::FunctionRetTy::Ty(code_gen::ty(
221-
format!("{}<'a, JsonBody<T>> where T: Serialize", &builder_name).as_ref(),
221+
format!("{}<'a, 'b, JsonBody<T>> where T: Serialize", &builder_name).as_ref(),
222222
)),
223223
)
224224
};
@@ -467,13 +467,13 @@ impl<'a> RequestBuilder<'a> {
467467
let (builder_expr, builder_impl) = {
468468
if supports_body {
469469
(
470-
quote!(#builder_ident<'a, B>),
471-
quote!(impl<'a, B> #builder_ident<'a, B> where B: Body),
470+
quote!(#builder_ident<'a, 'b, B>),
471+
quote!(impl<'a, 'b, B> #builder_ident<'a, 'b, B> where B: Body),
472472
)
473473
} else {
474474
(
475-
quote!(#builder_ident<'a>),
476-
quote!(impl<'a> #builder_ident<'a>),
475+
quote!(#builder_ident<'a, 'b>),
476+
quote!(impl<'a, 'b> #builder_ident<'a, 'b>),
477477
)
478478
}
479479
};
@@ -509,7 +509,7 @@ impl<'a> RequestBuilder<'a> {
509509
#[derive(Clone, Debug)]
510510
#[doc = #builder_doc]
511511
pub struct #builder_expr {
512-
client: Elasticsearch,
512+
client: &'a Elasticsearch,
513513
parts: #enum_ty,
514514
#(#fields),*,
515515
}
@@ -546,10 +546,12 @@ impl<'a> RequestBuilder<'a> {
546546
let (fn_name, builder_ident_ret) = {
547547
let i = ident(name);
548548
let b = builder_ident.clone();
549-
if endpoint.supports_body() {
550-
(quote!(#i<'a>), quote!(#b<'a, ()>))
551-
} else {
552-
(quote!(#i<'a>), quote!(#b<'a>))
549+
550+
match (endpoint.supports_body(), is_root_method) {
551+
(true, true) => (quote!(#i<'a, 'b>), quote!(#b<'a, 'b, ()>)),
552+
(false, true) => (quote!(#i<'a, 'b>), quote!(#b<'a, 'b>)),
553+
(true, false) => (quote!(#i<'b>), quote!(#b<'a, 'b, ()>)),
554+
(false, false) => (quote!(#i<'b>), quote!(#b<'a, 'b>)),
553555
}
554556
};
555557

@@ -560,24 +562,24 @@ impl<'a> RequestBuilder<'a> {
560562

561563
let clone_expr = {
562564
if is_root_method {
563-
quote!(self.clone())
565+
quote!(&self)
564566
} else {
565-
quote!(self.client.clone())
567+
quote!(&self.client)
566568
}
567569
};
568570

569571
if enum_builder.contains_single_parameterless_part() {
570572
quote!(
571573
#method_doc
572-
pub fn #fn_name(&self) -> #builder_ident_ret {
574+
pub fn #fn_name(&'a self) -> #builder_ident_ret {
573575
#builder_ident::new(#clone_expr)
574576
}
575577
)
576578
} else {
577579
let (enum_ty, _, _) = enum_builder.clone().build();
578580
quote!(
579581
#method_doc
580-
pub fn #fn_name(&self, parts: #enum_ty) -> #builder_ident_ret {
582+
pub fn #fn_name(&'a self, parts: #enum_ty) -> #builder_ident_ret {
581583
#builder_ident::new(#clone_expr, parts)
582584
}
583585
)

api_generator/src/api_generator/code_gen/url/enum_builder.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl<'a> EnumBuilder<'a> {
178178

179179
let (enum_ty, generics) = {
180180
if self.has_lifetime {
181-
(ty_a(self.ident.as_ref()), generics_a())
181+
(ty_b(self.ident.as_ref()), generics_b())
182182
} else {
183183
(ty(self.ident.as_ref()), generics_none())
184184
}
@@ -365,25 +365,25 @@ mod tests {
365365

366366
let (enum_ty, enum_decl, enum_impl) = EnumBuilder::from(&endpoint).build();
367367

368-
assert_eq!(ty_a("SearchParts"), enum_ty);
368+
assert_eq!(ty_b("SearchParts"), enum_ty);
369369

370370
let expected_decl = quote!(
371371
#[derive(Debug, Clone, PartialEq)]
372372
#[doc = "API parts for the Search API"]
373-
pub enum SearchParts<'a> {
373+
pub enum SearchParts<'b> {
374374
#[doc = "No parts"]
375375
None,
376376
#[doc = "Index"]
377-
Index(&'a [&'a str]),
377+
Index(&'b [&'b str]),
378378
#[doc = "Index and Type"]
379-
IndexType(&'a [&'a str], &'a [&'a str]),
379+
IndexType(&'b [&'b str], &'b [&'b str]),
380380
}
381381
);
382382

383383
ast_eq(expected_decl, enum_decl);
384384

385385
let expected_impl = quote!(
386-
impl<'a> SearchParts<'a> {
386+
impl<'b> SearchParts<'b> {
387387
#[doc = "Builds a relative URL path to the Search API"]
388388
pub fn url(self) -> Cow<'static, str> {
389389
match self {

0 commit comments

Comments
 (0)