Skip to content

fix expanded-corpus generation: media types, validation patterns, paths, allOf aliases - #47

Merged
lightsofapollo merged 7 commits into
mainfrom
fix/corpus-generation-fixes
Jul 29, 2026
Merged

fix expanded-corpus generation: media types, validation patterns, paths, allOf aliases#47
lightsofapollo merged 7 commits into
mainfrom
fix/corpus-generation-fixes

Conversation

@lightsofapollo

Copy link
Copy Markdown
Contributor

What

Probe-driven bug fixes from running 241 previously-failing APIs.guru specs (AWS, Adyen, apisetu.gov.in, api.video, …) through client and server generation. 210/240 now generate cleanly (was ~2% at the start of the probe).

Fixes

Area Fix
Schema analysis allOf: [$ref, {description}] self-references are type aliases again — recursive expansion overflowed the stack on AWS-style specs (3+ specs crashed)
Media classification application/pdf → Binary; application/xml + +xml suffixes → Text (responses and requests); best_content() falls back to character-data media so XML-only request bodies are no longer unsupported
Validation patterns Java POSIX classes (\p{Print}, \p{Alpha}, …) → ASCII ranges; ECMA \uXXXX → Rust \u{XXXX}; legacy octal \000\x00. Patterns that still can't compile offline (look-around, backreferences) degrade to "no pattern check" instead of failing the whole spec
Validation extensions AWS x-pattern promotes to the standard pattern keyword
Validation bundle Component keys prefixed so a schema named id (real AWS DataPipeline spec) survives draft-4 meta-schema validation
Paths AWS query markers (/tags/{arn}#tagKeys) strip the #fragment; webhook synthetic paths gain their leading /
Server codegen Non-canonical schema names (not-found) are qualified with their canonical Rust identifiers via rust_type_name()

Each fix ships with regression tests; full suite is green (75 test targets).

Remaining known gaps (fail loudly, not silently wrong)

  • Form-style object-array query items (19 specs) — the AWS query-protocol wire shape (param.N.Prop) is undefined by OpenAPI; generator rejects explicitly rather than guessing
  • Multipart server extraction (not implemented)
  • YAML tab-indentation parse errors (3 specs: Adyen ×2, Amadeus) — invalid YAML upstream
  • One apicurio spec with a string where a PathItem is expected — invalid spec

Test plan

  • cargo test — all green
  • 241-spec APIs.guru re-probe: 210/240 pass, categorized remainder

…hs, allOf aliases

Probe-driven fixes from running 241 previously-failing APIs.guru specs
(AWS, Adyen, apisetu.gov.in, api.video, ...) through client and server
generation. 210/240 now generate cleanly (was ~2%):

- allOf [$ref, {description}] self-references are type aliases again;
  recursive expansion overflowed the stack on AWS-style specs.
- application/pdf responses classify as Binary; application/xml and +xml
  suffixed types classify as Text on both response and request sides.
- best_content() falls back to character-data media (text/xml etc.)
  instead of leaving XML-only request bodies unsupported.
- Validation pattern normalization: Java POSIX classes (\p{Print},
  \p{Alpha}, ...) translate to ASCII ranges, ECMA \uXXXX escapes to
  Rust \u{XXXX}, legacy octal escapes to \xNN. Patterns that still
  cannot compile offline (look-around, backreferences) degrade to
  "no pattern check" instead of failing generation.
- AWS x-pattern extension promotes to the standard pattern keyword.
- Validation bundle component keys are prefixed so a schema named like
  a JSON Schema keyword (`id`) survives meta-schema validation.
- AWS query markers (/tags/{arn}#tagKeys) strip the #fragment before
  route generation; webhook synthetic paths gain their leading `/`.
- Server code qualifies non-canonical schema names (not-found) with
  their canonical Rust identifiers via rust_type_name().

Remaining known gaps (fail loudly, not silently wrong): form-style
object-array query items (AWS query protocol wire shape is undefined
by OpenAPI), multipart server extraction, YAML tab-indentation specs,
and one PathItem-as-string spec.
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openapi-to-rust Ready Ready Preview, Comment Jul 29, 2026 2:37am

Request Review

AWS query-protocol specs (sqs, docdb, ec2, elasticache, neptune, rds,
redshift) declare form-style array parameters whose items reference a
flat structure — every property scalar — such as Tag { Key, Value }.
These now project to `Vec<T>` and serialize symmetrically on the wire
as `param.N.Prop=value` (e.g. `tags.1.Key=env&tags.1.Value=prod`):

- New ArrayItemType::FlatStructRef carries the resolved property names
  so client and server emit identical keys without re-resolving.
- Item refs wrapped in annotation-only allOf (AWS's
  `items: {allOf: [$ref, {xml}]}` idiom) are seen through, mirroring
  the type-alias rule.
- The generated server groups `param.N.Prop` pairs by N and decodes
  each group as one JSON object so serde fills the struct.
- Nested structures (arrays/objects below one level) stay rejected:
  their wire shape below depth one is service-specific, and the
  generator fails loudly rather than guessing.

Also fixes a client parse failure on EC2: wire property names like
`Type` were emitted as bare field idents (`item.type`); they now route
through the model generator's keyword escaping (`item.r#type`).

Regression coverage: server_query_roundtrip_test gains a Tag-array
parameter exercised end-to-end — the generated client emits
`tags.1.Key=env&tags.1.Value=prod` and the generated Axum server
observes typed `Vec<Tag>` values.
Real-world specs (Adyen CheckoutService/PaymentService, Amadeus
trip-parser) carry literal tab characters inside block-scalar prose,
which serde_yaml rejects outright per YAML 1.2's tab-indentation rule.
parse_spec now retries once with tabs sanitized line-wise: tabs on
whitespace-only lines drop away (blank lines carry no indent
semantics), content tabs become a single space, keeping block-scalar
indent auto-detection consistent with sibling prose lines.

Adds a debug escape hatch used while hunting a client parse failure:
OATR_DUMP_TOKENS_ON_PARSE_ERROR=<path> writes the generated token
stream when syn rejects it.
@lightsofapollo
lightsofapollo merged commit 2a373f9 into main Jul 29, 2026
12 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