From f96b3cafcf19b0208eb887bbd09e53dc5c4f7264 Mon Sep 17 00:00:00 2001
From: Marco Napetti <nappa85@therocktrading.com>
Date: Tue, 2 Mar 2021 16:17:27 +0100
Subject: [PATCH 1/3] Proposed solution for issue 8833

---
 .../main/resources/rust/reqwest/api.mustache  | 28 ++++++++--------
 .../rust/reqwest/configuration.mustache       | 32 +++++++++++++++----
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
index 977f0b6edbc..884a090354d 100644
--- a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
+++ b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
@@ -80,7 +80,7 @@ pub enum {{{operationIdCamelCase}}}Error {
 /// {{{.}}}
 {{/notes}}
 {{#vendorExtensions.x-group-parameters}}
-pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: &configuration::Configuration{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error<{{{operationIdCamelCase}}}Error>> {
+pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error<{{{operationIdCamelCase}}}Error>> {
     // unbox the parameters
     {{#allParams}}
     let {{paramName}} = params.{{paramName}};
@@ -111,12 +111,13 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
     {{#isApiKey}}
     {{#isKeyInQuery}}
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.query(&[("{{{keyParamName}}}", local_var_value)]);
+        if let Some(local_var_key) = local_var_apikey.get_key("{{{keyParamName}}}") {
+            let local_var_value = match local_var_apikey.get_prefix("{{{keyParamName}}}") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.query(&[("{{{keyParamName}}}", local_var_value)]);
+        }
     }
     {{/isKeyInQuery}}
     {{/isApiKey}}
@@ -150,12 +151,13 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
     {{#isApiKey}}
     {{#isKeyInHeader}}
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.header("{{{keyParamName}}}", local_var_value);
+        if let Some(local_var_key) = local_var_apikey.get_key("{{{keyParamName}}}") {
+            let local_var_value = match local_var_apikey.get_prefix("{{{keyParamName}}}") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.header("{{{keyParamName}}}", local_var_value);
+        }
     };
     {{/isKeyInHeader}}
     {{/isApiKey}}
diff --git a/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache b/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache
index 2c9b243a6d3..80d9fe45a3b 100644
--- a/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache
@@ -2,31 +2,49 @@
 
 use reqwest;
 
-pub struct Configuration {
+pub struct Configuration<A: ApiKey> {
     pub base_path: String,
     pub user_agent: Option<String>,
     pub client: reqwest::Client,
     pub basic_auth: Option<BasicAuth>,
     pub oauth_access_token: Option<String>,
     pub bearer_access_token: Option<String>,
-    pub api_key: Option<ApiKey>,
+    pub api_key: Option<A>,
     // TODO: take an oauth2 token source, similar to the go one
 }
 
 pub type BasicAuth = (String, Option<String>);
 
-pub struct ApiKey {
-    pub prefix: Option<String>,
-    pub key: String,
+pub trait ApiKey {
+    fn get_prefix(&self, name: &str) -> Option<String>,
+    fn get_key(&self, name: &str) -> Option<String>,
 }
 
-impl Configuration {
+impl ApiKey for String {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, _: &str) -> Option<String> {
+      self.cloned()
+    }
+}
+
+impl ApiKey for std::collection::HashMap<String, String> {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, name: &str) -> Option<String> {
+      self.get(name).cloned()
+    }
+}
+
+impl<A: ApiKey> Configuration<A> {
     pub fn new() -> Configuration {
         Configuration::default()
     }
 }
 
-impl Default for Configuration {
+impl<A: ApiKey> Default for Configuration<A> {
     fn default() -> Self {
         Configuration {
             base_path: "{{{basePath}}}".to_owned(),
-- 
GitLab


From e20cc05aa778557e594df3547749a2bacf81e651 Mon Sep 17 00:00:00 2001
From: Marco Napetti <nappa85@therocktrading.com>
Date: Tue, 2 Mar 2021 16:17:27 +0100
Subject: [PATCH 2/3] Proposed solution for issue 8833

---
 .../main/resources/rust/reqwest/api.mustache  | 28 ++++++++--------
 .../rust/reqwest/configuration.mustache       | 32 +++++++++++++++----
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
index 977f0b6edbc..884a090354d 100644
--- a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
+++ b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
@@ -80,7 +80,7 @@ pub enum {{{operationIdCamelCase}}}Error {
 /// {{{.}}}
 {{/notes}}
 {{#vendorExtensions.x-group-parameters}}
-pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: &configuration::Configuration{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error<{{{operationIdCamelCase}}}Error>> {
+pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error<{{{operationIdCamelCase}}}Error>> {
     // unbox the parameters
     {{#allParams}}
     let {{paramName}} = params.{{paramName}};
@@ -111,12 +111,13 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
     {{#isApiKey}}
     {{#isKeyInQuery}}
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.query(&[("{{{keyParamName}}}", local_var_value)]);
+        if let Some(local_var_key) = local_var_apikey.get_key("{{{keyParamName}}}") {
+            let local_var_value = match local_var_apikey.get_prefix("{{{keyParamName}}}") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.query(&[("{{{keyParamName}}}", local_var_value)]);
+        }
     }
     {{/isKeyInQuery}}
     {{/isApiKey}}
@@ -150,12 +151,13 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
     {{#isApiKey}}
     {{#isKeyInHeader}}
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.header("{{{keyParamName}}}", local_var_value);
+        if let Some(local_var_key) = local_var_apikey.get_key("{{{keyParamName}}}") {
+            let local_var_value = match local_var_apikey.get_prefix("{{{keyParamName}}}") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.header("{{{keyParamName}}}", local_var_value);
+        }
     };
     {{/isKeyInHeader}}
     {{/isApiKey}}
diff --git a/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache b/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache
index 2c9b243a6d3..80d9fe45a3b 100644
--- a/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/rust/reqwest/configuration.mustache
@@ -2,31 +2,49 @@
 
 use reqwest;
 
-pub struct Configuration {
+pub struct Configuration<A: ApiKey> {
     pub base_path: String,
     pub user_agent: Option<String>,
     pub client: reqwest::Client,
     pub basic_auth: Option<BasicAuth>,
     pub oauth_access_token: Option<String>,
     pub bearer_access_token: Option<String>,
-    pub api_key: Option<ApiKey>,
+    pub api_key: Option<A>,
     // TODO: take an oauth2 token source, similar to the go one
 }
 
 pub type BasicAuth = (String, Option<String>);
 
-pub struct ApiKey {
-    pub prefix: Option<String>,
-    pub key: String,
+pub trait ApiKey {
+    fn get_prefix(&self, name: &str) -> Option<String>,
+    fn get_key(&self, name: &str) -> Option<String>,
 }
 
-impl Configuration {
+impl ApiKey for String {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, _: &str) -> Option<String> {
+      self.cloned()
+    }
+}
+
+impl ApiKey for std::collection::HashMap<String, String> {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, name: &str) -> Option<String> {
+      self.get(name).cloned()
+    }
+}
+
+impl<A: ApiKey> Configuration<A> {
     pub fn new() -> Configuration {
         Configuration::default()
     }
 }
 
-impl Default for Configuration {
+impl<A: ApiKey> Default for Configuration<A> {
     fn default() -> Self {
         Configuration {
             base_path: "{{{basePath}}}".to_owned(),
-- 
GitLab


From bcbcebec2aaf33129206f6c24d5d4bfec50b7ce5 Mon Sep 17 00:00:00 2001
From: Marco Napetti <nappa85@therocktrading.com>
Date: Wed, 3 Mar 2021 11:35:45 +0100
Subject: [PATCH 3/3] regenerated samples

---
 .../petstore-async/src/apis/configuration.rs  | 32 +++++++++++++++----
 .../petstore-async/src/apis/pet_api.rs        | 29 +++++++++--------
 .../petstore-async/src/apis/store_api.rs      | 21 ++++++------
 .../petstore-async/src/apis/user_api.rs       | 16 +++++-----
 .../petstore/src/apis/configuration.rs        | 32 +++++++++++++++----
 .../rust/reqwest/petstore/src/apis/pet_api.rs | 13 ++++----
 .../reqwest/petstore/src/apis/store_api.rs    | 13 ++++----
 7 files changed, 98 insertions(+), 58 deletions(-)

diff --git a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/configuration.rs b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/configuration.rs
index 4194f7a52d1..a4a16171bdf 100644
--- a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/configuration.rs
+++ b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/configuration.rs
@@ -11,31 +11,49 @@
 
 use reqwest;
 
-pub struct Configuration {
+pub struct Configuration<A: ApiKey> {
     pub base_path: String,
     pub user_agent: Option<String>,
     pub client: reqwest::Client,
     pub basic_auth: Option<BasicAuth>,
     pub oauth_access_token: Option<String>,
     pub bearer_access_token: Option<String>,
-    pub api_key: Option<ApiKey>,
+    pub api_key: Option<A>,
     // TODO: take an oauth2 token source, similar to the go one
 }
 
 pub type BasicAuth = (String, Option<String>);
 
-pub struct ApiKey {
-    pub prefix: Option<String>,
-    pub key: String,
+pub trait ApiKey {
+    fn get_prefix(&self, name: &str) -> Option<String>,
+    fn get_key(&self, name: &str) -> Option<String>,
 }
 
-impl Configuration {
+impl ApiKey for String {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, _: &str) -> Option<String> {
+      self.cloned()
+    }
+}
+
+impl ApiKey for std::collection::HashMap<String, String> {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, name: &str) -> Option<String> {
+      self.get(name).cloned()
+    }
+}
+
+impl<A: ApiKey> Configuration<A> {
     pub fn new() -> Configuration {
         Configuration::default()
     }
 }
 
-impl Default for Configuration {
+impl<A: ApiKey> Default for Configuration<A> {
     fn default() -> Self {
         Configuration {
             base_path: "http://petstore.swagger.io/v2".to_owned(),
diff --git a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/pet_api.rs
index e4162a33129..a15061ab3b4 100644
--- a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/pet_api.rs
+++ b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/pet_api.rs
@@ -207,7 +207,7 @@ pub enum UploadFileError {
 }
 
 
-pub async fn add_pet(configuration: &configuration::Configuration, params: AddPetParams) -> Result<ResponseContent<AddPetSuccess>, Error<AddPetError>> {
+pub async fn add_pet<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: AddPetParams) -> Result<ResponseContent<AddPetSuccess>, Error<AddPetError>> {
     // unbox the parameters
     let body = params.body;
 
@@ -242,7 +242,7 @@ pub async fn add_pet(configuration: &configuration::Configuration, params: AddPe
     }
 }
 
-pub async fn delete_pet(configuration: &configuration::Configuration, params: DeletePetParams) -> Result<ResponseContent<DeletePetSuccess>, Error<DeletePetError>> {
+pub async fn delete_pet<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: DeletePetParams) -> Result<ResponseContent<DeletePetSuccess>, Error<DeletePetError>> {
     // unbox the parameters
     let pet_id = params.pet_id;
     let api_key = params.api_key;
@@ -281,7 +281,7 @@ pub async fn delete_pet(configuration: &configuration::Configuration, params: De
 }
 
 /// Multiple status values can be provided with comma separated strings
-pub async fn find_pets_by_status(configuration: &configuration::Configuration, params: FindPetsByStatusParams) -> Result<ResponseContent<FindPetsByStatusSuccess>, Error<FindPetsByStatusError>> {
+pub async fn find_pets_by_status<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: FindPetsByStatusParams) -> Result<ResponseContent<FindPetsByStatusSuccess>, Error<FindPetsByStatusError>> {
     // unbox the parameters
     let status = params.status;
 
@@ -317,7 +317,7 @@ pub async fn find_pets_by_status(configuration: &configuration::Configuration, p
 }
 
 /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
-pub async fn find_pets_by_tags(configuration: &configuration::Configuration, params: FindPetsByTagsParams) -> Result<ResponseContent<FindPetsByTagsSuccess>, Error<FindPetsByTagsError>> {
+pub async fn find_pets_by_tags<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: FindPetsByTagsParams) -> Result<ResponseContent<FindPetsByTagsSuccess>, Error<FindPetsByTagsError>> {
     // unbox the parameters
     let tags = params.tags;
 
@@ -353,7 +353,7 @@ pub async fn find_pets_by_tags(configuration: &configuration::Configuration, par
 }
 
 /// Returns a single pet
-pub async fn get_pet_by_id(configuration: &configuration::Configuration, params: GetPetByIdParams) -> Result<ResponseContent<GetPetByIdSuccess>, Error<GetPetByIdError>> {
+pub async fn get_pet_by_id<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: GetPetByIdParams) -> Result<ResponseContent<GetPetByIdSuccess>, Error<GetPetByIdError>> {
     // unbox the parameters
     let pet_id = params.pet_id;
 
@@ -367,12 +367,13 @@ pub async fn get_pet_by_id(configuration: &configuration::Configuration, params:
         local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
     }
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        if let Some(local_var_key) = local_var_apikey.get_key("api_key") {
+            let local_var_value = match local_var_apikey.get_prefix("api_key") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        }
     };
 
     let local_var_req = local_var_req_builder.build()?;
@@ -392,7 +393,7 @@ pub async fn get_pet_by_id(configuration: &configuration::Configuration, params:
     }
 }
 
-pub async fn update_pet(configuration: &configuration::Configuration, params: UpdatePetParams) -> Result<ResponseContent<UpdatePetSuccess>, Error<UpdatePetError>> {
+pub async fn update_pet<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: UpdatePetParams) -> Result<ResponseContent<UpdatePetSuccess>, Error<UpdatePetError>> {
     // unbox the parameters
     let body = params.body;
 
@@ -427,7 +428,7 @@ pub async fn update_pet(configuration: &configuration::Configuration, params: Up
     }
 }
 
-pub async fn update_pet_with_form(configuration: &configuration::Configuration, params: UpdatePetWithFormParams) -> Result<ResponseContent<UpdatePetWithFormSuccess>, Error<UpdatePetWithFormError>> {
+pub async fn update_pet_with_form<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: UpdatePetWithFormParams) -> Result<ResponseContent<UpdatePetWithFormSuccess>, Error<UpdatePetWithFormError>> {
     // unbox the parameters
     let pet_id = params.pet_id;
     let name = params.name;
@@ -471,7 +472,7 @@ pub async fn update_pet_with_form(configuration: &configuration::Configuration,
     }
 }
 
-pub async fn upload_file(configuration: &configuration::Configuration, params: UploadFileParams) -> Result<ResponseContent<UploadFileSuccess>, Error<UploadFileError>> {
+pub async fn upload_file<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: UploadFileParams) -> Result<ResponseContent<UploadFileSuccess>, Error<UploadFileError>> {
     // unbox the parameters
     let pet_id = params.pet_id;
     let additional_metadata = params.additional_metadata;
diff --git a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/store_api.rs b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/store_api.rs
index 21647faa062..a3a0ffc6e39 100644
--- a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/store_api.rs
+++ b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/store_api.rs
@@ -102,7 +102,7 @@ pub enum PlaceOrderError {
 
 
 /// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
-pub async fn delete_order(configuration: &configuration::Configuration, params: DeleteOrderParams) -> Result<ResponseContent<DeleteOrderSuccess>, Error<DeleteOrderError>> {
+pub async fn delete_order<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: DeleteOrderParams) -> Result<ResponseContent<DeleteOrderSuccess>, Error<DeleteOrderError>> {
     // unbox the parameters
     let order_id = params.order_id;
 
@@ -134,7 +134,7 @@ pub async fn delete_order(configuration: &configuration::Configuration, params:
 }
 
 /// Returns a map of status codes to quantities
-pub async fn get_inventory(configuration: &configuration::Configuration) -> Result<ResponseContent<GetInventorySuccess>, Error<GetInventoryError>> {
+pub async fn get_inventory<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>) -> Result<ResponseContent<GetInventorySuccess>, Error<GetInventoryError>> {
     // unbox the parameters
 
 
@@ -147,12 +147,13 @@ pub async fn get_inventory(configuration: &configuration::Configuration) -> Resu
         local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
     }
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        if let Some(local_var_key) = local_var_apikey.get_key("api_key") {
+            let local_var_value = match local_var_apikey.get_prefix("api_key") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        }
     };
 
     let local_var_req = local_var_req_builder.build()?;
@@ -173,7 +174,7 @@ pub async fn get_inventory(configuration: &configuration::Configuration) -> Resu
 }
 
 /// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
-pub async fn get_order_by_id(configuration: &configuration::Configuration, params: GetOrderByIdParams) -> Result<ResponseContent<GetOrderByIdSuccess>, Error<GetOrderByIdError>> {
+pub async fn get_order_by_id<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: GetOrderByIdParams) -> Result<ResponseContent<GetOrderByIdSuccess>, Error<GetOrderByIdError>> {
     // unbox the parameters
     let order_id = params.order_id;
 
@@ -204,7 +205,7 @@ pub async fn get_order_by_id(configuration: &configuration::Configuration, param
     }
 }
 
-pub async fn place_order(configuration: &configuration::Configuration, params: PlaceOrderParams) -> Result<ResponseContent<PlaceOrderSuccess>, Error<PlaceOrderError>> {
+pub async fn place_order<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: PlaceOrderParams) -> Result<ResponseContent<PlaceOrderSuccess>, Error<PlaceOrderError>> {
     // unbox the parameters
     let body = params.body;
 
diff --git a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/user_api.rs b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/user_api.rs
index a791bfbc9bb..c53fc37d489 100644
--- a/samples/client/petstore/rust/reqwest/petstore-async/src/apis/user_api.rs
+++ b/samples/client/petstore/rust/reqwest/petstore-async/src/apis/user_api.rs
@@ -195,7 +195,7 @@ pub enum UpdateUserError {
 
 
 /// This can only be done by the logged in user.
-pub async fn create_user(configuration: &configuration::Configuration, params: CreateUserParams) -> Result<ResponseContent<CreateUserSuccess>, Error<CreateUserError>> {
+pub async fn create_user<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: CreateUserParams) -> Result<ResponseContent<CreateUserSuccess>, Error<CreateUserError>> {
     // unbox the parameters
     let body = params.body;
 
@@ -227,7 +227,7 @@ pub async fn create_user(configuration: &configuration::Configuration, params: C
     }
 }
 
-pub async fn create_users_with_array_input(configuration: &configuration::Configuration, params: CreateUsersWithArrayInputParams) -> Result<ResponseContent<CreateUsersWithArrayInputSuccess>, Error<CreateUsersWithArrayInputError>> {
+pub async fn create_users_with_array_input<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: CreateUsersWithArrayInputParams) -> Result<ResponseContent<CreateUsersWithArrayInputSuccess>, Error<CreateUsersWithArrayInputError>> {
     // unbox the parameters
     let body = params.body;
 
@@ -259,7 +259,7 @@ pub async fn create_users_with_array_input(configuration: &configuration::Config
     }
 }
 
-pub async fn create_users_with_list_input(configuration: &configuration::Configuration, params: CreateUsersWithListInputParams) -> Result<ResponseContent<CreateUsersWithListInputSuccess>, Error<CreateUsersWithListInputError>> {
+pub async fn create_users_with_list_input<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: CreateUsersWithListInputParams) -> Result<ResponseContent<CreateUsersWithListInputSuccess>, Error<CreateUsersWithListInputError>> {
     // unbox the parameters
     let body = params.body;
 
@@ -292,7 +292,7 @@ pub async fn create_users_with_list_input(configuration: &configuration::Configu
 }
 
 /// This can only be done by the logged in user.
-pub async fn delete_user(configuration: &configuration::Configuration, params: DeleteUserParams) -> Result<ResponseContent<DeleteUserSuccess>, Error<DeleteUserError>> {
+pub async fn delete_user<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: DeleteUserParams) -> Result<ResponseContent<DeleteUserSuccess>, Error<DeleteUserError>> {
     // unbox the parameters
     let username = params.username;
 
@@ -323,7 +323,7 @@ pub async fn delete_user(configuration: &configuration::Configuration, params: D
     }
 }
 
-pub async fn get_user_by_name(configuration: &configuration::Configuration, params: GetUserByNameParams) -> Result<ResponseContent<GetUserByNameSuccess>, Error<GetUserByNameError>> {
+pub async fn get_user_by_name<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: GetUserByNameParams) -> Result<ResponseContent<GetUserByNameSuccess>, Error<GetUserByNameError>> {
     // unbox the parameters
     let username = params.username;
 
@@ -354,7 +354,7 @@ pub async fn get_user_by_name(configuration: &configuration::Configuration, para
     }
 }
 
-pub async fn login_user(configuration: &configuration::Configuration, params: LoginUserParams) -> Result<ResponseContent<LoginUserSuccess>, Error<LoginUserError>> {
+pub async fn login_user<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: LoginUserParams) -> Result<ResponseContent<LoginUserSuccess>, Error<LoginUserError>> {
     // unbox the parameters
     let username = params.username;
     let password = params.password;
@@ -388,7 +388,7 @@ pub async fn login_user(configuration: &configuration::Configuration, params: Lo
     }
 }
 
-pub async fn logout_user(configuration: &configuration::Configuration) -> Result<ResponseContent<LogoutUserSuccess>, Error<LogoutUserError>> {
+pub async fn logout_user<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>) -> Result<ResponseContent<LogoutUserSuccess>, Error<LogoutUserError>> {
     // unbox the parameters
 
 
@@ -419,7 +419,7 @@ pub async fn logout_user(configuration: &configuration::Configuration) -> Result
 }
 
 /// This can only be done by the logged in user.
-pub async fn update_user(configuration: &configuration::Configuration, params: UpdateUserParams) -> Result<ResponseContent<UpdateUserSuccess>, Error<UpdateUserError>> {
+pub async fn update_user<A: configuration::ApiKey>(configuration: &configuration::Configuration<A>, params: UpdateUserParams) -> Result<ResponseContent<UpdateUserSuccess>, Error<UpdateUserError>> {
     // unbox the parameters
     let username = params.username;
     let body = params.body;
diff --git a/samples/client/petstore/rust/reqwest/petstore/src/apis/configuration.rs b/samples/client/petstore/rust/reqwest/petstore/src/apis/configuration.rs
index 4194f7a52d1..a4a16171bdf 100644
--- a/samples/client/petstore/rust/reqwest/petstore/src/apis/configuration.rs
+++ b/samples/client/petstore/rust/reqwest/petstore/src/apis/configuration.rs
@@ -11,31 +11,49 @@
 
 use reqwest;
 
-pub struct Configuration {
+pub struct Configuration<A: ApiKey> {
     pub base_path: String,
     pub user_agent: Option<String>,
     pub client: reqwest::Client,
     pub basic_auth: Option<BasicAuth>,
     pub oauth_access_token: Option<String>,
     pub bearer_access_token: Option<String>,
-    pub api_key: Option<ApiKey>,
+    pub api_key: Option<A>,
     // TODO: take an oauth2 token source, similar to the go one
 }
 
 pub type BasicAuth = (String, Option<String>);
 
-pub struct ApiKey {
-    pub prefix: Option<String>,
-    pub key: String,
+pub trait ApiKey {
+    fn get_prefix(&self, name: &str) -> Option<String>,
+    fn get_key(&self, name: &str) -> Option<String>,
 }
 
-impl Configuration {
+impl ApiKey for String {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, _: &str) -> Option<String> {
+      self.cloned()
+    }
+}
+
+impl ApiKey for std::collection::HashMap<String, String> {
+    fn get_prefix(&self, _: &str) -> Option<String> {
+      None
+    }
+    fn get_key(&self, name: &str) -> Option<String> {
+      self.get(name).cloned()
+    }
+}
+
+impl<A: ApiKey> Configuration<A> {
     pub fn new() -> Configuration {
         Configuration::default()
     }
 }
 
-impl Default for Configuration {
+impl<A: ApiKey> Default for Configuration<A> {
     fn default() -> Self {
         Configuration {
             base_path: "http://petstore.swagger.io/v2".to_owned(),
diff --git a/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs
index 47cf47f1d59..43d79279050 100644
--- a/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs
+++ b/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs
@@ -218,12 +218,13 @@ pub fn get_pet_by_id(configuration: &configuration::Configuration, pet_id: i64)
         local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
     }
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        if let Some(local_var_key) = local_var_apikey.get_key("api_key") {
+            let local_var_value = match local_var_apikey.get_prefix("api_key") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        }
     };
 
     let local_var_req = local_var_req_builder.build()?;
diff --git a/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs b/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs
index 898599f9b2f..f99d4334ec4 100644
--- a/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs
+++ b/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs
@@ -88,12 +88,13 @@ pub fn get_inventory(configuration: &configuration::Configuration, ) -> Result<:
         local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
     }
     if let Some(ref local_var_apikey) = configuration.api_key {
-        let local_var_key = local_var_apikey.key.clone();
-        let local_var_value = match local_var_apikey.prefix {
-            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
-            None => local_var_key,
-        };
-        local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        if let Some(local_var_key) = local_var_apikey.get_key("api_key") {
+            let local_var_value = match local_var_apikey.get_prefix("api_key") {
+                Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
+                None => local_var_key,
+            };
+            local_var_req_builder = local_var_req_builder.header("api_key", local_var_value);
+        }
     };
 
     let local_var_req = local_var_req_builder.build()?;
-- 
GitLab