Skip to content

Add PATCH/HEAD/OPTIONS support; fix trait method visibility and enum query params - #14

Merged
dxx merged 3 commits into
dxx:devfrom
LiJoeAllen:dev
Aug 26, 2026
Merged

Add PATCH/HEAD/OPTIONS support; fix trait method visibility and enum query params#14
dxx merged 3 commits into
dxx:devfrom
LiJoeAllen:dev

Conversation

@LiJoeAllen

@LiJoeAllen LiJoeAllen commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Three improvements developed while building an OpenAPI-to-feignhttp code generator (feignhttp-generator) that emits #[feign] trait clients and exercises them with wire-level integration tests.

1. PATCH / HEAD / OPTIONS method support (c9d5d69)

  • codegen/src/enu.rs: add Patch / Head / Options to the Method enum plus from_str / to_str mappings.
  • codegen/src/lib.rs: expose #[patch], #[head], #[options] attribute macros.
  • reqwest supports these verbs natively; the generic method-string passthrough in func.rs needed no changes.
  • New example examples/method.rs.

2. Generated trait client methods were private (f5cd066)

The #[feign] macro on a trait generates a shadow struct plus an inherent impl TraitName { ... } containing the request methods. trait_method_to_item_fn hard-coded method visibility to Visibility::Inherited (private), so:

  • Upstream's own tests passed only because test code lives in the same module as the macro expansion.
  • Any cross-module or cross-crate consumer got E0624: method is private — which makes externally generated clients unusable.

Fix: pass the trait's visibility into fn_to_streams_for_trait -> trait_method_to_item_fn and use it for the emitted methods.

3. Enums could not be used as query parameters (2902696)

filter_struct classifies any non-primitive type as "struct", routing enum query args into ser::to_map. MapSerializer::serialize_unit_variant returns Serialize("not support unit_variant"), so #[query("granularity")] g: MyEnum always failed at runtime, even though ValueSerializer already handles unit variants.

Fix:

  • Add ser::to_pairs (PairsSerializer): ordered key-value collection where structs emit one pair per field, bare scalars/unit variants emit a single empty-key pair, None emits nothing, and newtype variants emit (variant, inner).
  • Emit to_pairs in both struct-query sites of func.rs; an empty key falls back to the Rust argument name. Behavior for real structs is unchanged.

Testing

  • Upstream suite: all tests pass except pre-existing mockito socket-bind environment failures (os error 10013) unrelated to these changes; all examples compile.
  • New external consumer crate (module layout, cross-crate): 11/11 runtime tests green against a stub HTTP server, covering URL template substitution, path/query/header/form/multipart serialization, JSON decode with renames, octet-stream bytes, HEAD/OPTIONS, enum queries, and typed error parsing via ErrorKind::Status.

@LiJoeAllen LiJoeAllen changed the title Add PATCH/HEAD/OPTIONS method support Add PATCH/HEAD/OPTIONS support; fix trait method visibility and enum query params Aug 26, 2026
@LiJoeAllen

Copy link
Copy Markdown
Contributor Author

@dxx 😄 O(∩_∩)O 😄

@dxx

dxx commented Aug 26, 2026

Copy link
Copy Markdown
Owner

@LiJoeAllen Thanks for your PR.

@dxx
dxx merged commit cf980d4 into dxx:dev Aug 26, 2026
@dxx

dxx commented Aug 26, 2026

Copy link
Copy Markdown
Owner

@LiJoeAllen Hi, I think HEAD and OPTIONS aren't useful for feignhttp because response headers can't be retrieved. Can we remove them?

@LiJoeAllen

Copy link
Copy Markdown
Contributor Author

ok

@LiJoeAllen

Copy link
Copy Markdown
Contributor Author

Sure! Since feignhttp can't retrieve response headers, HEAD/OPTIONS indeed aren't useful here. I've removed them in #15, keeping only PATCH. Thanks!

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.

2 participants