Skip to content

fix(client): emit typed enum for const/enum on parameter schemas#13

Merged
lightsofapollo merged 2 commits into
mainfrom
feat/issue-10-const-on-parameter
May 8, 2026
Merged

fix(client): emit typed enum for const/enum on parameter schemas#13
lightsofapollo merged 2 commits into
mainfrom
feat/issue-10-const-on-parameter

Conversation

@lightsofapollo
Copy link
Copy Markdown
Contributor

Summary

Follow-up to issue #10 (comment): PR #12 fixed string const inside schema components, but the parameter pipeline is a separate code path. A path/query parameter declared with { "type": "string", "const": "X" } (or enum: [...]) on its inline schema still generated impl AsRef<str>, letting callers pass any value even though only one (or a fixed set) is valid.

  • ParameterInfo gains enum_values: Option<Vec<String>> (with skip_serializing_if, so existing snapshots are unchanged).
  • analyze_parameter detects string-enum/const on the inline parameter schema and produces a synthetic enum type name (<OperationId><ParamName>).
  • Client generator emits the inline enum with Display, AsRef<str>, an as_str() helper, and serde rename attrs — placed before the impl HttpClient block.
  • Existing path/query templating (format!("{}", v) / v.to_string() for non-String rust_types) picks up the new type via Display, so no call-site changes were needed.
  • Bonus: same code path also fixes explicit enum: [...] on parameter schemas, which was previously emitted as impl AsRef<str> too.

Before / after

For the issue commenter's spec:

{ "name": "the_constant", "in": "path",
  "schema": { "type": "string", "const": "MyConstantValue" } }

Before:

pub async fn some_const_operation(&self, the_constant: impl AsRef<str>) -> ...

After:

pub enum SomeConstOperationTheConstant {
    #[serde(rename = "MyConstantValue")]
    MyConstantValue,
}
// + Display, AsRef<str>, as_str() impls

pub async fn some_const_operation(
    &self,
    the_constant: SomeConstOperationTheConstant,
) -> ...

Test plan

  • cargo build
  • cargo test — full suite, 0 failures, no snapshot churn
  • cargo fmt --check
  • cargo clippy --lib -- -D warnings
  • New tests/const_only_parameter_test.rs covers:
    • const-only path parameter → single-variant enum
    • enum: [...] path parameter → multi-variant enum (bonus fix)
    • const-only optional query parameter → Option<Enum>
    • Display and AsRef<str> impls are emitted

🤖 Generated with Claude Code

lightsofapollo and others added 2 commits May 7, 2026 21:26
PR #12 fixed string `const` inside schema components, but the parameter
pipeline is a separate code path: a path/query parameter declared with
`{ "type": "string", "const": "X" }` (or `enum: [...]`) on its inline
schema still generated `impl AsRef<str>`, letting callers pass any value
even though only one (or a fixed set) is valid.

Extend `ParameterInfo` with `enum_values` and detect the string-enum
case in `analyze_parameter`. The client generator emits a synthetic
inline enum (`<OperationId><ParamName>`) with `Display`, `AsRef<str>`,
and an `as_str()` helper, plus serde rename attrs. The existing
path/query templating uses `format!("{}", v)` / `v.to_string()` for
non-`String` rust_types, so Display makes it work without call-site
changes.

The same code path also fixes explicit `enum: [...]` on parameter
schemas, which was previously generated as `impl AsRef<str>` too.

`enum_values` uses `skip_serializing_if = "Option::is_none"` so existing
parameter snapshots are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lightsofapollo lightsofapollo merged commit 77023a2 into main May 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant