refactor: add Into derives to nutype types with domain operations #334
No reviewers
Labels
No labels
adr
automated
bug
chore
dependencies
documentation
enhancement
epic
github-actions
P1-high
P2-medium
P3-low
release
research
rust
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jwilger/eventcore!334
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "refactor/245-nutype-into-conversion"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Into,PartialOrd, andOrdderives to nutype domain types (StreamId,StreamPrefix,StreamVersion,StreamPosition,BatchSize)MoneyAmountarithmetic in domain operations:AccountBalancegainsdeposit(),withdraw(),has_sufficient_funds(),balance_cents()methodsFrom<MoneyAmount> for i32for fold-based balance computationsVec<MoneyAmount>withsort()instead ofVec<u16>with raw extractiontest_amount(N)instead of raw literalsinto_inner()at IO boundaries (SQL params, logging) — unchangedTest plan
Closes #245
Agreed — the
{ let v: u16 = (*amount).into(); v }pattern is ugly. This happened because nutype'sIntoderive generatesInto<inner_type>but Rust can't infer the target type in these contexts, forcing the explicit binding.Looking at the overall review comment too: for test-only types like
MoneyAmount, I thinkFrom<MoneyAmount> for i32is the right fix. Domain functions (add/subtract) would be overkill here sinceMoneyAmountonly exists in test files.For the production nutype types (
StreamVersion,BatchSize, etc.) that have the same ugly pattern in the backends, I'll revert those back tointo_inner()— it was actually cleaner before. TheIntoderive is useful for contexts where.into()type inference works naturally, but not for these explicit-cast-needed spots.Fixing in the next push.
Will fix with
From<MoneyAmount> for u16— then these become just(*amount).into()oramount.into().@ -350,24 +368,24 @@ async fn concurrent_transfers_produce_consistent_final_state() {.collect();Same fix —
From<MoneyAmount> for u16.Fixed. The approach now:
AccountBalancehas domain methods:deposit(),withdraw(),has_sufficient_funds(),balance_cents()From<MoneyAmount> for i32for fold-based balance computationsVec<MoneyAmount>withsort()(derivedOrd) — no raw value extractiontest_amount(N)instead of raw literalsWithdraw::handle()usesstate.has_sufficient_funds(self.amount)instead of extracting inner valuesAlso created guardrails PR #340 (merged) codifying the domain-type-operations rule so this pattern is enforced going forward.
Fixed — collections now hold
Vec<MoneyAmount>directly, no extraction needed.@ -350,24 +368,24 @@ async fn concurrent_transfers_produce_consistent_final_state() {.collect();Fixed — same approach,
Some(*amount)keeps the domain type.