feat(thread_aware): add feature-gated ThreadAware impls for 3rd-party crate types#478
feat(thread_aware): add feature-gated ThreadAware impls for 3rd-party crate types#478martin-kolinek wants to merge 9 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #478 +/- ##
=======================================
Coverage 100.0% 100.0%
=======================================
Files 335 340 +5
Lines 25586 25683 +97
=======================================
+ Hits 25586 25683 +97 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR extends the thread_aware crate with opt-in, feature-gated ThreadAware implementations for a set of commonly used third-party value types, while keeping the default build free of extra dependencies.
Changes:
- Adds
third_partysubmodules that provide no-opThreadAwareimpls for types frombytes,chrono,http,jiff,time, anduuid, each behind a dedicated Cargo feature. - Updates crate documentation/README to describe the new opt-in feature set.
- Adds optional dependencies + feature wiring in
crates/thread_aware/Cargo.tomland updatesallowed_external_typesfor CI’s external-type checking.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/thread_aware/src/lib.rs | Documents the new third-party impl feature set and wires in the third_party module. |
| crates/thread_aware/src/third_party/mod.rs | Introduces a private helper macro and per-feature submodules for third-party impls. |
| crates/thread_aware/src/third_party/bytes.rs | No-op ThreadAware impls + tests for bytes::Bytes / BytesMut. |
| crates/thread_aware/src/third_party/chrono.rs | No-op ThreadAware impls + tests for selected chrono value/time types. |
| crates/thread_aware/src/third_party/http.rs | No-op ThreadAware impls + tests for http inert value types (StatusCode, Version, Method). |
| crates/thread_aware/src/third_party/jiff.rs | No-op ThreadAware impls + tests for selected jiff types, explicitly omitting Zoned. |
| crates/thread_aware/src/third_party/time.rs | No-op ThreadAware impls + tests for selected time types, explicitly omitting Instant. |
| crates/thread_aware/src/third_party/uuid.rs | No-op ThreadAware impl + tests for uuid::Uuid. |
| crates/thread_aware/README.md | Regenerated README reflecting the new feature set. |
| crates/thread_aware/Cargo.toml | Adds per-crate features, optional deps, and expands allowed_external_types. |
| Cargo.lock | Updates lockfile to reflect the new optional dependencies in thread_aware. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
🤖 Fixed in 404dcdb: made AI response generated by Road to Gas Town |
sandersaares
left a comment
There was a problem hiding this comment.
time::Instant (requires std feature on time)
I am not sure why this is an omission. Do we really intend to support no-std? Feels unnecessary. If someone is using our SDK, we can assume they are using the standard library.
… crate types Adds opt-in ThreadAware implementations for commonly-used 3rd-party types behind per-crate Cargo features. By default this crate brings no additional dependencies; users enable only the features they need. New features and the types they cover: - `bytes`: `Bytes`, `BytesMut` - `chrono`: `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `TimeDelta`, `Utc`, `FixedOffset`, `Weekday`, `Month`, `DateTime<Utc>`, `DateTime<FixedOffset>` - `http`: `StatusCode`, `Version`, `Method` - `jiff`: `Timestamp`, `Span`, `SignedDuration`, `civil::Date`, `civil::Time`, `civil::DateTime`, `civil::ISOWeekDate` - `time`: `Date`, `Time`, `PrimitiveDateTime`, `OffsetDateTime`, `UtcOffset`, `Duration`, `Weekday`, `Month` - `uuid`: `Uuid` Motivated by a Contributors-channel discussion (Evgenii Shutov) and the ox-sdk!5243054 PR adding ThreadAware impls for UuidId/UuidString wrappers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reviewer noted that the crate-level docs link to `third_party` but the module was private, causing the link to resolve as an external crate. Make `third_party` and its feature-gated submodules `pub` so users can navigate to a module page that documents which types each feature covers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… http, drop chrono+time Addresses reviewer feedback on PR #478: * Rename features to embed the wrapped crate's major (or 0.x minor): `bytes_v1`, `http_v1`, `jiff_v0_2`, `uuid_v1`. This lets us support a future `bytes 2.0` / `jiff 0.3` additively (as e.g. `bytes_v2`) without a breaking release of `thread_aware` (martintmk, Vaiz, sandersaares). * Drop the `chrono` and `time` features; both are treated as legacy as the ecosystem aligns on `jiff` (martintmk). * Expand `http_v1` to cover `HeaderName`, `HeaderValue`, `HeaderMap<T>`, `Request<T>`, `Response<T>`. Containers propagate `relocate` to inner `T` like `Vec<T>`/`Box<T>` (martintmk). * Switch the per-feature gates on submodules and the macro to `any(test, feature = ...)` and move `bytes`/`http`/`jiff`/`uuid` to unconditional `dev-dependencies` so `cargo test` exercises all third-party impls without needing to enable any feature flags (sandersaares). * Reword the `# Features` doc block to avoid the misleading 'optional dependency' phrasing when a feature is enabled (sandersaares). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
404dcdb to
4b4664b
Compare
1dec8f8 to
72f7529
Compare
Without the cfg gate, building with --no-default-features (e.g. coverage CI) defines the macro unconditionally while all its callers are gated to feature/test, causing unused_macros to fire under -D warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
72f7529 to
63c5549
Compare
Address review comments on PR #478: Request/Response now relocate every header value in addition to the body, consistent with the documented HeaderMap propagation behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rMap Adds tests that populate header maps before calling relocate, covering the new header-propagation loops added in fa83ffd and restoring full patch coverage on codecov. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a Counter helper type whose relocate increments an observable counter, and use it in HeaderMap<Counter>, Request<Counter>, Response<Counter> tests so mutation testing can detect when the parent impls' relocate bodies are replaced with (). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Clarify that no-feature default avoids pulling in *wrapped* crates, not all dependencies (derive is still a default dep). - Document that http::Extensions are not (and cannot be) relocated by Request/Response impls. - Rename request_relocate_propagates_to_body -> ..._to_body_and_headers since it now covers both. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Counter and its ThreadAware impl are only used by relocate tests gated on feature = threads. Without the gate, --no-default-features builds (coverage CI) fail with dead-code warnings under -D warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Adds opt-in
ThreadAwareimplementations for commonly-used 3rd-party types behind per-crate, version-suffixed Cargo features. By default this crate brings no additional dependencies; users enable only the features they need.Motivation
Discussed in the Oxidizer Contributors channel (thread by Evgenii Shutov), and inspired by ox-sdk!5243054 which adds
ThreadAwareforUuidId<T>/UuidStringwrappers arounduuid::Uuid. Many users wrap or re-export 3rd-party primitive/value types and need them to satisfyThreadAwareto flow through APIs that require it. Doing this in user crates requires the newtype dance; offering the impls here behind opt-in features removes that friction without forcing the dependencies on anyone.Design
Each supported crate gets its own version-suffixed Cargo feature; enabling it pulls in that crate as an optional dependency and adds blanket
ThreadAwareimpls for its plain value types via a small private macro. The version suffix lets a future major version of the wrapped crate land additively (e.g.bytes_v2) without forcing a breaking release ofthread_aware. The default feature set is unchanged.bytes_v1Bytes,BytesMuthttp_v1StatusCode,Version,Method,HeaderName,HeaderValue,HeaderMap<T: ThreadAware>,Request<T: ThreadAware>,Response<T: ThreadAware>jiff_v0_2Timestamp,Span,SignedDuration,civil::Date,civil::Time,civil::DateTime,civil::ISOWeekDateuuid_v1UuidHeaderMap<T>,Request<T>, andResponse<T>propagaterelocateto every header value and (forRequest/Response) the body, mirroring how this crate handlesVec<T>andBox<T>.Intentional omissions
jiff::Zoned(carries a TimeZone reference; semantics warrant explicit user choice)http::Uri(holdsBytes/Arcinternals; can be added later if needed)chronoandtime(deferred per reviewer feedback; can be added later aschrono_v0_4/time_v0_3if needed)Files
crates/thread_aware/src/third_party/{mod,bytes_v1,http_v1,jiff_v0_2,uuid_v1}.rs— one submodule per supported crate version, each gated by#[cfg(any(test, feature = "..."))].mod.rsdefines a privateimpl_noop_thread_aware!macro used by submodules with inert value types.bytes,http,jiff,uuid) are unconditional[dev-dependencies]so the test suite exercises every impl withcargo test(no features required).ThreadAware/Send/Syncand a smoke test on the threaded runtime.allowed_external_typesBecause impls on foreign types make those types reachable through this crate's public surface,
cargo_check_external_types(run with--all-featuresin CI) flags them. Explicit type paths are listed inCargo.toml(rather than wildcards) for visibility.Verification
cargo clippy --all-features --all-targets -- -D warnings✅cargo test --all-features✅ (126 unit + integration + 14 doctests)cargo test --tests --no-default-features --workspace✅just format,just readme,just spellcheck,cargo sort --check --grouped --workspace✅