From 2cd9aea5a464878e4c0e523de5cd3711eb6e0cbe Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 5 Feb 2026 16:15:01 +0100 Subject: [PATCH 1/2] Fix query param array with reference This commit fixes an error in the codegen for API request param defined as array which reference another schema object. The generated code to parse an individual array item used the argument type (`Vec`) so the generated code didn't compile (trying to `p.parse::>()` instead of `p.parse::()`). --- openapi-lambda-codegen/src/api/operation/parameter.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openapi-lambda-codegen/src/api/operation/parameter.rs b/openapi-lambda-codegen/src/api/operation/parameter.rs index 188424c..41c473b 100644 --- a/openapi-lambda-codegen/src/api/operation/parameter.rs +++ b/openapi-lambda-codegen/src/api/operation/parameter.rs @@ -67,7 +67,15 @@ impl CodeGenerator { })), .. }) => match item_ref_or_schema { - ReferenceOr::Reference { .. } => Some(required_type.clone()), + ReferenceOr::Reference { .. } => Some( + self + .inline_ref_or_schema( + item_ref_or_schema, + components_schemas, + GeneratedModels::Done(generated_models), + ) + .0, + ), ReferenceOr::Item(item_schema) if !is_plain_string_schema(item_schema) => Some( self .inline_ref_or_schema( From f4df5c7ead285d6906ea8cca505d4027337b3cb3 Mon Sep 17 00:00:00 2001 From: "David A. Ramos" Date: Mon, 16 Feb 2026 20:37:10 -0800 Subject: [PATCH 2/2] Add test for parameter enum array --- openapi-lambda-test/spec/bar.yaml | 13 ++++ ...pi_lambda_test__tests__bar_handler.rs.snap | 1 + ...ambda_test__tests__openapi-apigw.yaml.snap | 15 ++++ .../openapi_lambda_test__tests__out.rs.snap | 69 +++++++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/openapi-lambda-test/spec/bar.yaml b/openapi-lambda-test/spec/bar.yaml index 8176810..9b93344 100644 --- a/openapi-lambda-test/spec/bar.yaml +++ b/openapi-lambda-test/spec/bar.yaml @@ -22,6 +22,19 @@ path: - B - "1" - "" + - name: type-array + in: query + description: Bar array type + schema: + type: array + items: + type: string + # Inline enum should generate a new model. + enum: + - a + - B + - "1" + - "" - name: x-bar in: header schema: diff --git a/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__bar_handler.rs.snap b/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__bar_handler.rs.snap index 4e5a027..e7c5f04 100644 --- a/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__bar_handler.rs.snap +++ b/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__bar_handler.rs.snap @@ -44,6 +44,7 @@ impl Api for BarApiHandler { bar_id: crate::types::BarId, sort_by: Option, r#type: Option, + type_array: Option>, x_bar: Option, request_body: Vec, headers: HeaderMap, diff --git a/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__openapi-apigw.yaml.snap b/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__openapi-apigw.yaml.snap index 6d0d7e4..7563006 100644 --- a/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__openapi-apigw.yaml.snap +++ b/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__openapi-apigw.yaml.snap @@ -68,6 +68,14 @@ paths: schema: $ref: "#/components/schemas/CreateBarTypeParam" style: form + - in: query + name: type-array + description: Bar array type + schema: + type: array + items: + $ref: "#/components/schemas/CreateBarTypeArrayParamItem" + style: form - in: header name: x-bar schema: @@ -134,6 +142,13 @@ components: - B - "1" - "" + CreateBarTypeArrayParamItem: + type: string + enum: + - a + - B + - "1" + - "" responses: FooOk: description: Successful operation diff --git a/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__out.rs.snap b/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__out.rs.snap index 89d97a0..cc6630d 100644 --- a/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__out.rs.snap +++ b/openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__out.rs.snap @@ -10,6 +10,44 @@ pub mod models { use openapi_lambda::models::chrono; #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] #[serde(crate = "openapi_lambda::__private::serde")] + pub enum CreateBarTypeArrayParamItem { + #[serde(rename = "a")] + A, + B, + #[serde(rename = "1")] + __1, + #[serde(rename = "")] + EmptyString, + } + impl CreateBarTypeArrayParamItem { + fn as_str(&self) -> &'static str { + match self { + Self::A => "a", + Self::B => "B", + Self::__1 => "1", + Self::EmptyString => "", + } + } + } + impl std::fmt::Display for CreateBarTypeArrayParamItem { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } + } + impl std::str::FromStr for CreateBarTypeArrayParamItem { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + match s { + "a" => Ok(Self::A), + "B" => Ok(Self::B), + "1" => Ok(Self::__1), + "" => Ok(Self::EmptyString), + _ => Err(anyhow!("invalid enum variant `{}`", s)), + } + } + } + #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] + #[serde(crate = "openapi_lambda::__private::serde")] pub enum CreateBarTypeParam { #[serde(rename = "a")] A, @@ -230,6 +268,7 @@ pub mod bar { #[doc = concat!("* `", stringify!(bar_id), "` - ", "")] #[doc = concat!("* `", stringify!(sort_by), "` - ", "")] #[doc = concat!("* `", stringify!(r#type), "` - ", "Bar type")] + #[doc = concat!("* `", stringify!(type_array), "` - ", "Bar array type")] #[doc = concat!("* `", stringify!(x_bar), "` - ", "")] #[doc = concat!("* `request_body` - ", "Request body")] /// * `headers` - HTTP request headers @@ -244,6 +283,7 @@ pub mod bar { bar_id: crate::types::BarId, sort_by: Option, r#type: Option, + type_array: Option>, x_bar: Option, request_body: Vec, headers: HeaderMap, @@ -360,6 +400,31 @@ pub mod bar { Err(err) => return api.respond_to_event_error(err).await, }; #[allow(clippy::bind_instead_of_map)] + let type_array = match request + .multi_value_query_string_parameters + .all("type-array") + .map(|param_values| { + param_values + .iter() + .copied() + .map(|p| { + p.parse::() + .map_err(|err| { + EventError::InvalidRequestQueryParam { + param_name: std::borrow::Cow::Borrowed("type-array"), + source: Some(err.into()), + backtrace: Backtrace::new(), + } + }) + }) + .collect::, _>>() + }) + .transpose() + { + Ok(param_value) => param_value, + Err(err) => return api.respond_to_event_error(err).await, + }; + #[allow(clippy::bind_instead_of_map)] let x_bar = match request .headers .get("x-bar") @@ -447,6 +512,9 @@ pub mod bar { log::trace!(concat!("Request parameter `", "barId", "`: {:#?}"), bar_id); log::trace!(concat!("Request parameter `", "sortBy", "`: {:#?}"), sort_by); log::trace!(concat!("Request parameter `", "type", "`: {:#?}"), r#type); + log::trace!( + concat!("Request parameter `", "type-array", "`: {:#?}"), type_array + ); log::trace!(concat!("Request parameter `", "x-bar", "`: {:#?}"), x_bar); log::trace!("Request body: {request_body:#?}"); log::trace!("Authenticating request"); @@ -470,6 +538,7 @@ pub mod bar { bar_id, sort_by, r#type, + type_array, x_bar, request_body, headers,