Priority: P2
Describe the issue
wreq-ruby documents its native API through Ruby stub files, but those stubs are not an executable contract and several signatures have drifted from v1.2.4 runtime behavior:
Wreq::Headers documents [], []=, to_h, and blockless each, but those methods/behavior are missing.
Response#text is declared with a default_encoding: keyword, while the native method accepts a positional encoding string.
- request
body: is documented as String or IO, while the native converter accepts only String or Wreq::BodySender.
- native methods expose rest-argument reflection (
parameters # => [[:rest]]), so editors cannot infer the real keywords and overloads.
For a public native gem, documentation, static signatures, and the loaded extension should describe the same API.
Proposed deliverables
- Ship
sig/wreq.rbs in the gem with the complete public API.
- Model the URL inputs actually supported by runtime, optional keywords, block/no-block enumeration, nilable response metadata, and typed exceptions. RBS should describe rather than silently introduce coercions.
- Keep YARD/RDoc stubs, examples, and RBS generated from or checked against one reviewed contract where practical.
- Add runtime contract tests for public method presence, intentional aliases, blockless Enumerator behavior, constructor arity, and representative argument shapes.
- Run
rbs validate in CI and execute documentation examples that do not require public network access.
An internal native method may still use *args; a small Ruby wrapper with explicit keywords is reasonable when it materially improves reflection, validation, and error messages. RBS alone should not be used to excuse permissive runtime behavior.
Acceptance criteria
- The packaged gem contains valid RBS for every public class, module function, method, constant family, and exception.
rbs validate passes against supported Ruby versions.
- Public examples and signatures use the same positional/keyword forms as the native extension.
- CI fails when a documented method is absent or when a blockless collection method does not return an Enumerator as declared.
- Wrong argument shapes still raise at runtime; signatures do not replace input validation.
- The typing work adds no required runtime dependency for untyped callers.
Ruby ecosystem precedent
RBS is Ruby's standard signature language, and gems conventionally package signatures under sig/. Native extensions benefit especially because Ruby reflection cannot recover Rust/C argument and return types automatically.
The same transport's Python binding ships py.typed plus typed public Python modules, providing direct precedent for treating binding signatures as part of the distributed package.
Relevant wreq-ruby source
Priority: P2
Describe the issue
wreq-ruby documents its native API through Ruby stub files, but those stubs are not an executable contract and several signatures have drifted from v1.2.4 runtime behavior:
Wreq::Headersdocuments[],[]=,to_h, and blocklesseach, but those methods/behavior are missing.Response#textis declared with adefault_encoding:keyword, while the native method accepts a positional encoding string.body:is documented as String or IO, while the native converter accepts only String orWreq::BodySender.parameters # => [[:rest]]), so editors cannot infer the real keywords and overloads.For a public native gem, documentation, static signatures, and the loaded extension should describe the same API.
Proposed deliverables
sig/wreq.rbsin the gem with the complete public API.rbs validatein CI and execute documentation examples that do not require public network access.An internal native method may still use
*args; a small Ruby wrapper with explicit keywords is reasonable when it materially improves reflection, validation, and error messages. RBS alone should not be used to excuse permissive runtime behavior.Acceptance criteria
rbs validatepasses against supported Ruby versions.Ruby ecosystem precedent
RBS is Ruby's standard signature language, and gems conventionally package signatures under
sig/. Native extensions benefit especially because Ruby reflection cannot recover Rust/C argument and return types automatically.The same transport's Python binding ships
py.typedplus typed public Python modules, providing direct precedent for treating binding signatures as part of the distributed package.Relevant wreq-ruby source
lib/wreq.rblib/wreq_rubysrc/client.rssrc/client/resp.rs