Description
Implement Locale as a ValueObject in the primitives module.
Spec: BCP 47 language tag (e.g. en-US, cs-CZ)
Implementation checklist
Implementation detail
Input / Output
|
Type |
Alias |
| Input |
String |
LocaleInput |
| Output |
String |
LocaleOutput |
Normalization
Trim; normalise the separator: accept both _ and - as separators between the language and region subtags, store with - (BCP 47 canonical form). Lowercase the language subtag, uppercase the region subtag if present (e.g. "en_us" → "en-US").
Validation
Must match BCP 47 at a structural level — for MVP, a two-part rule is sufficient:
- Language subtag: 2–3 ASCII letters (lowercase after normalisation).
- Optional region subtag (after
-): exactly 2 ASCII letters (uppercase after normalisation) OR exactly 3 digits.
- Other subtag types (script, variant, extension) are out of scope for MVP.
Extra methods
None beyond the trait.
References
Description
Implement
Localeas aValueObjectin theprimitivesmodule.Spec: BCP 47 language tag (e.g.
en-US,cs-CZ)Implementation checklist
src/primitives/locale.rsValueObjecttrait#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]src/primitives/mod.rsandprelude# ExampleblockROADMAP.mdfrom ⬜ to ✅Implementation detail
Input / Output
StringLocaleInputStringLocaleOutputNormalization
Trim; normalise the separator: accept both
_and-as separators between the language and region subtags, store with-(BCP 47 canonical form). Lowercase the language subtag, uppercase the region subtag if present (e.g."en_us"→"en-US").Validation
Must match BCP 47 at a structural level — for MVP, a two-part rule is sufficient:
-): exactly 2 ASCII letters (uppercase after normalisation) OR exactly 3 digits.Extra methods
None beyond the trait.
References