From fc2295b5a21394f31e08a956bce7db749a6b8a6a Mon Sep 17 00:00:00 2001 From: Aman Rao Date: Wed, 11 Feb 2026 09:57:22 +0530 Subject: [PATCH 1/3] Fixes #22900 --- .../main/resources/rust/reqwest/api.mustache | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 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 1fda2948cc4b..244bee079c61 100644 --- a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache +++ b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache @@ -422,19 +422,41 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: {{#supportAsync}} {{^required}} if let Some(ref param_value) = {{{vendorExtensions.x-rust-param-identifier}}} { - let file = TokioFile::open(param_value).await?; + {{#isArray}} + for value in param_value { + let file = TokioFile::open(value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("{{{baseName}}}", file_part); + } + {{/isArray}} + {{^isArray}} + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("{{{baseName}}}", file_part); + {{/isArray}} + } + {{/required}} + {{#required}} + {{#isArray}} + for value in &{{{vendorExtensions.x-rust-param-identifier}}} { + let file = TokioFile::open(value).await?; let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_name = value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); multipart_form = multipart_form.part("{{{baseName}}}", file_part); } - {{/required}} - {{#required}} - let file = TokioFile::open(&{{{vendorExtensions.x-rust-param-identifier}}}).await?; + {{/isArray}} + {{^isArray}} + let file = TokioFile::open({{{vendorExtensions.x-rust-param-identifier}}}).await?; let stream = FramedRead::new(file, BytesCodec::new()); let file_name = {{{vendorExtensions.x-rust-param-identifier}}}.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); multipart_form = multipart_form.part("{{{baseName}}}", file_part); + {{/isArray}} {{/required}} {{/supportAsync}} {{/isFile}} From 10160b2e2fb1942c5e1c0857b6a52697ce5207da Mon Sep 17 00:00:00 2001 From: Aman Rao Date: Wed, 11 Feb 2026 12:32:46 +0530 Subject: [PATCH 2/3] fixed non async block generation when Vec (files) are present --- .../main/resources/rust/reqwest/api.mustache | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) 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 244bee079c61..5224b0c4d9b5 100644 --- a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache +++ b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache @@ -404,18 +404,44 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: {{^supportAsync}} {{#required}} {{^isNullable}} + {{#isArray}} + for value in &{{{vendorExtensions.x-rust-param-identifier}}} { + multipart_form = multipart_form.file("{{{baseName}}}", value)?; + } + {{/isArray}} + {{^isArray}} multipart_form = multipart_form.file("{{{baseName}}}", {{{vendorExtensions.x-rust-param-identifier}}})?; + {{/isArray}} {{/isNullable}} {{#isNullable}} + {{#isArray}} + match {{{vendorExtensions.x-rust-param-identifier}}} { + Some(param_value) => { + for value in param_value { + multipart_form = multipart_form.file("{{{baseName}}}", value)?; + } + }, + None => { unimplemented!("Required nullable form file param not supported"); }, + } + {{/isArray}} + {{^isArray}} match {{{vendorExtensions.x-rust-param-identifier}}} { Some(param_value) => { multipart_form = multipart_form.file("{{{baseName}}}", param_value)?; }, None => { unimplemented!("Required nullable form file param not supported"); }, } + {{/isArray}} {{/isNullable}} {{/required}} {{^required}} if let Some(ref param_value) = {{{vendorExtensions.x-rust-param-identifier}}} { + {{#isArray}} + for value in param_value { + multipart_form = multipart_form.file("{{{baseName}}}", value)?; + } + {{/isArray}} + {{^isArray}} multipart_form = multipart_form.file("{{{baseName}}}", param_value)?; + {{/isArray}} } {{/required}} {{/supportAsync}} @@ -451,7 +477,7 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: } {{/isArray}} {{^isArray}} - let file = TokioFile::open({{{vendorExtensions.x-rust-param-identifier}}}).await?; + let file = TokioFile::open(&{{{vendorExtensions.x-rust-param-identifier}}}).await?; let stream = FramedRead::new(file, BytesCodec::new()); let file_name = {{{vendorExtensions.x-rust-param-identifier}}}.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); From 76bd2e56a786ded42631bfc580aa1e0d3db8c1f1 Mon Sep 17 00:00:00 2001 From: Aman Rao Date: Wed, 11 Feb 2026 13:53:03 +0530 Subject: [PATCH 3/3] updated samples with reqwest multipart form change --- .../multipart-async/src/apis/default_api.rs | 20 +++++++++---------- .../src/apis/pet_api.rs | 10 +++++----- .../src/apis/pet_api.rs | 10 +++++----- .../petstore-async/src/apis/pet_api.rs | 10 +++++----- .../petstore-avoid-box/src/apis/pet_api.rs | 10 +++++----- .../src/apis/pet_api.rs | 10 +++++----- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/samples/client/others/rust/reqwest/multipart-async/src/apis/default_api.rs b/samples/client/others/rust/reqwest/multipart-async/src/apis/default_api.rs index ecc8c0e6632c..e51b6c4759de 100644 --- a/samples/client/others/rust/reqwest/multipart-async/src/apis/default_api.rs +++ b/samples/client/others/rust/reqwest/multipart-async/src/apis/default_api.rs @@ -94,11 +94,11 @@ pub async fn upload_multiple_fields(configuration: &configuration::Configuration let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); multipart_form = multipart_form.part("primaryFile", file_part); if let Some(ref param_value) = params.thumbnail { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("thumbnail", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("thumbnail", file_part); } req_builder = req_builder.multipart(multipart_form); @@ -141,11 +141,11 @@ pub async fn upload_optional_file(configuration: &configuration::Configuration, multipart_form = multipart_form.text("metadata", param_value.to_string()); } if let Some(ref param_value) = params.file { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("file", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("file", file_part); } req_builder = req_builder.multipart(multipart_form); diff --git a/samples/client/petstore/rust/reqwest/petstore-async-middleware/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore-async-middleware/src/apis/pet_api.rs index a3ba46c92709..59704a34c6b0 100644 --- a/samples/client/petstore/rust/reqwest/petstore-async-middleware/src/apis/pet_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore-async-middleware/src/apis/pet_api.rs @@ -570,11 +570,11 @@ pub async fn upload_file(configuration: &configuration::Configuration, params: U multipart_form = multipart_form.text("additionalMetadata", param_value.to_string()); } if let Some(ref param_value) = params.file { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("file", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("file", file_part); } req_builder = req_builder.multipart(multipart_form); diff --git a/samples/client/petstore/rust/reqwest/petstore-async-tokensource/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore-async-tokensource/src/apis/pet_api.rs index 1ceed076f06c..4eb848b73962 100644 --- a/samples/client/petstore/rust/reqwest/petstore-async-tokensource/src/apis/pet_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore-async-tokensource/src/apis/pet_api.rs @@ -581,11 +581,11 @@ pub async fn upload_file(configuration: &configuration::Configuration, params: U multipart_form = multipart_form.text("additionalMetadata", param_value.to_string()); } if let Some(ref param_value) = params.file { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("file", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("file", file_part); } req_builder = req_builder.multipart(multipart_form); 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 a3ba46c92709..59704a34c6b0 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 @@ -570,11 +570,11 @@ pub async fn upload_file(configuration: &configuration::Configuration, params: U multipart_form = multipart_form.text("additionalMetadata", param_value.to_string()); } if let Some(ref param_value) = params.file { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("file", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("file", file_part); } req_builder = req_builder.multipart(multipart_form); diff --git a/samples/client/petstore/rust/reqwest/petstore-avoid-box/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore-avoid-box/src/apis/pet_api.rs index a3ba46c92709..59704a34c6b0 100644 --- a/samples/client/petstore/rust/reqwest/petstore-avoid-box/src/apis/pet_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore-avoid-box/src/apis/pet_api.rs @@ -570,11 +570,11 @@ pub async fn upload_file(configuration: &configuration::Configuration, params: U multipart_form = multipart_form.text("additionalMetadata", param_value.to_string()); } if let Some(ref param_value) = params.file { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("file", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("file", file_part); } req_builder = req_builder.multipart(multipart_form); diff --git a/samples/client/petstore/rust/reqwest/petstore-serde-path-to-error/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore-serde-path-to-error/src/apis/pet_api.rs index 2adab42af534..a6ca5f2a33b4 100644 --- a/samples/client/petstore/rust/reqwest/petstore-serde-path-to-error/src/apis/pet_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore-serde-path-to-error/src/apis/pet_api.rs @@ -496,11 +496,11 @@ pub async fn upload_file(configuration: &configuration::Configuration, pet_id: i multipart_form = multipart_form.text("additionalMetadata", param_value.to_string()); } if let Some(ref param_value) = p_form_file { - let file = TokioFile::open(param_value).await?; - let stream = FramedRead::new(file, BytesCodec::new()); - let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); - let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); - multipart_form = multipart_form.part("file", file_part); + let file = TokioFile::open(param_value).await?; + let stream = FramedRead::new(file, BytesCodec::new()); + let file_name = param_value.file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_default(); + let file_part = reqwest::multipart::Part::stream(reqwest::Body::wrap_stream(stream)).file_name(file_name); + multipart_form = multipart_form.part("file", file_part); } req_builder = req_builder.multipart(multipart_form);