dev: replace unmaintained derivative crate with manual impls - #587
dev: replace unmaintained derivative crate with manual impls#587sshaplygin wants to merge 2 commits into
Conversation
`derivative` is flagged unmaintained by RUSTSEC-2024-0388, so every `cargo audit` run against a project depending on `ydb` reports it. It was used in three places, all for the same thing: derive `Debug` while skipping fields that are not `Debug` themselves. Replace each with a hand-written `Debug` impl listing the remaining fields, which produces the same output, and drop the dependency. - `TableSession`: skips `on_drop_callbacks` and `channel_pool`. - `RacyRoundRobinState`: skips the two `ConnectionTask` queues. - `GrpcConnectionManagerGeneric`: skips `interceptor`; its `Clone` also becomes a manual impl to keep the `BalancerT: Clone`-only bound that `derivative(Clone(bound = ...))` provided. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #587 +/- ##
==========================================
- Coverage 86.91% 86.89% -0.02%
==========================================
Files 198 198
Lines 19492 19615 +123
==========================================
+ Hits 16941 17044 +103
- Misses 2551 2571 +20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Codecov requires 80% patch coverage; this PR started at 25% because nothing in the test suite ever formatted the three types whose derives were replaced by hand-written impls. That gap matters more than the number. `derivative(Debug = "ignore")` enforced the skipped fields structurally, whereas a hand-written `debug_struct` chain can silently start or stop reporting a field. Each test now pins both halves of the contract: the fields that must appear, and the non-`Debug` fields that must not. - `TableSession`: reports id, can_pooled and timeouts; never `channel_pool` or `on_drop_callbacks`. The session construction that `discard_from_pool_clears_can_pooled` already used moves into a `test_session` helper shared by both tests. - `RacyRoundRobinState`: reports addrs and first_connection; never the connection queues. Uses a lazily connected channel, so no server is contacted, but it needs a Tokio reactor and is therefore async. - `GrpcConnectionManagerGeneric`: reports balancer, connections_pool and database; never the interceptor. Two further tests pin the `BalancerT: Clone`-only bound that `derivative(Clone(bound = ...))` provided, and that clones keep sharing one pool. Patch coverage 25% -> 100% (`cargo llvm-cov --lib`). Module coverage: grpc_connection_manager.rs 39.3% -> 71.6% lines, session.rs 67.1% -> 74.0%, connection_pool.rs 29.9% -> 39.8%. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Pushed The diff started at 25% because nothing in the suite ever formatted the three types whose derives this PR replaces. That is worth closing for its own sake, not just for the number —
Two extra tests pin the Nothing contacts a server: I checked the tests are not vacuous: dropping CoveragePatch coverage 100% (28/28 changed lines) under
🤖 Generated with Claude Code |
Problem
derivativeis flagged unmaintained by RUSTSEC-2024-0388 (upstream is no longer maintained; the advisory suggestsderive_more,derive-whereoreduce). Everycargo auditrun against a project depending onydbreports it.Change
It was used in exactly three places, all for the same thing: derive
Debugwhile skipping fields that are notDebugthemselves. Each becomes a hand-written impl listing the remaining fields, which produces identical output, and the dependency is dropped.TableSessionon_drop_callbacks,channel_poolRacyRoundRobinStateConnectionTaskqueuesGrpcConnectionManagerGenericinterceptorGrpcConnectionManagerGenericalso usedderivative(Clone(bound = "BalancerT: Clone")), so itsClonebecomes a manual impl too, preserving the balancer-only bound —ConnectionTsits behind anArcand does not needClone. ItsDebugkeeps theConnectionT: Debugbound thatderivativegenerated implicitly.No behaviour change:
derivative'sDebug = "ignore"omits the field entirely, which is whatdebug_struct(..).field(..).finish()emits.Verification
The
Cargo.lockdiff is exactly the removal ofderivative 2.2.0— no incidental version bumps.🤖 Generated with Claude Code