Why?
Our CLI currently uses many primitive types (String, i64, etc.) to represent domain concepts like client numbers, account IDs, and quote lengths. This makes validation scattered and fragile, increasing the risk of runtime errors and invalid user input slipping through. As suggested by Refactoring Guru – Primitive Obsession, defining small, dedicated value types improves:
- Type safety
- Input validation at construction
- Cleaner CLI parsing via
FromStr
- Self-documenting code (domain intent visible in function signatures)
What?
Introduce small, validated newtypes to replace raw primitives in CLI arguments and domain structures.
Each type should:
- Be a thin wrapper around a primitive
- Validate its input in a
new() constructor
- Implement
FromStr for easy integration with Clap (value_parser!())
Proposed types and constraints
| Type |
Underlying |
Constraint |
ClientNumber |
String |
Exactly 8 digits |
AccountId |
String |
Exactly 32 hex chars |
SymbolId |
String |
6–12 alphanumeric chars |
OrderQuantity |
u64 |
Positive, non-zero |
MoneyAmount |
f64 |
Positive, up to 2 decimals |
TransferReason |
String |
Optional, ≤ 50 chars (letters only) |
QuoteLength |
enum |
One of: 1, 5, 30, 90, 180, 365, 1825, 3650 |
QuotePeriod |
i64 |
Non-negative period value |
MfaCode |
String |
4–12 digits |
Password |
String |
Non-empty |
Main impact
- Stronger validation at input parsing time (fail-fast behavior)
- Reduced duplication of validation logic across commands
- Safer internal API and more expressive function signatures
- Minimal runtime overhead (just validation + wrapper)
Why?
Our CLI currently uses many primitive types (
String,i64, etc.) to represent domain concepts like client numbers, account IDs, and quote lengths. This makes validation scattered and fragile, increasing the risk of runtime errors and invalid user input slipping through. As suggested by Refactoring Guru – Primitive Obsession, defining small, dedicated value types improves:FromStrWhat?
Introduce small, validated newtypes to replace raw primitives in CLI arguments and domain structures.
Each type should:
new()constructorFromStrfor easy integration with Clap (value_parser!())Proposed types and constraints
ClientNumberStringAccountIdStringSymbolIdStringOrderQuantityu64MoneyAmountf64TransferReasonStringQuoteLengthenum1, 5, 30, 90, 180, 365, 1825, 3650QuotePeriodi64MfaCodeStringPasswordStringMain impact