feat(intid): add encode_int_base10 / decode_int_base10[_bounded]#81
Conversation
`yabase/intid` exposed encode/decode/bounded-decode helpers for
every other base (base32 RFC 4648 / Crockford, base36, base58
Bitcoin / Flickr, base62) but skipped decimal. The omission
broke switch-case bench harnesses ("swap base58 for base62 to
compare ID lengths, hit a compile error on
`encode_int_base10`") and forced callers to special-case decimal
with `int.to_string` / `int.parse` plus a hand-rolled bounds
check.
Add the missing trio:
- `encode_int_base10(value: Int) -> String`
- `decode_int_base10(input: String) -> Result(Int, CodecError)`
- `decode_int_base10_bounded(input:, max:) -> Result(Int, CodecError)`
All three route through `yabase/base10` (the existing
BitArray-level decimal codec) plus the same `int_to_bytes_be` /
`bytes_to_int` helpers the other `_int_*` functions use, so the
contract is byte-for-byte identical to base36 / base58 /
base62: empty input → `Error(InvalidLength(0))`, leading-zero
input is tolerated (matches the `decode_int_base36("0042") ==
decode_int_base36("42")` shape), `_bounded` returns
`Error(Overflow)` when the decoded value exceeds `max`.
Tests cover: zero, single-digit, two-digit carry, large value
(1B), empty rejection, round-trip, leading-zero tolerance,
invalid character mid-string, bounded under / at / over `max`.
Closes #78.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
yabase/intidexposed encode/decode/bounded-decode helpers forevery other base (base32 RFC 4648 / Crockford, base36, base58
Bitcoin / Flickr, base62) but skipped decimal. The omission broke
switch-case bench harnesses ("swap base58 for base62 to compare
ID lengths, hit a compile error on
encode_int_base10") andforced callers to special-case decimal with
int.to_string/int.parseplus a hand-rolled bounds check. Add the missingtrio.
Changes
src/yabase/intid.gleamyabase/base10.encode_int_base10(value: Int) -> String— routes throughbase10.encode(int_to_bytes_be(value)).decode_int_base10(input: String) -> Result(Int, CodecError)—routes through
base10.decode(input) |> result.map(bytes_to_int)with the same
reject_emptyguard as base36 / base58 / base62.decode_int_base10_bounded(input:, max:) -> Result(Int, CodecError)— wraps
decode_int_base10with the existingbound_check.base36 block to keep the source ordering by base value.
test/intid_test.gleam=== encoding.base10() (#78) ===test block covering:encode: zero, single-digit, two-digit carry, large value(1B).
decode: empty rejection, round-trip, leading-zerotolerance (
\"0042\" == \"42\"), invalid charactermid-string.
_bounded: under / at / overmaxboundary.CHANGELOG.md[Unreleased].Design Decisions
Why route through
base10rather thanint.to_string. Theissue's recommended approach was option 1 ("add the helpers for
symmetry"). Routing through
base10keeps the implementationbyte-for-byte identical to the other
encode_int_*functions,so the contract — empty input rejection, leading-zero
tolerance, byte-roundtrip semantics — matches without
case-by-case behaviour. Using
int.to_string/int.parsedirectly would diverge on the leading-zero case
(
int.parse(\"0042\") == Ok(42)doesn't preserve the\"0042\"shape on round-trip the way the byte path does).Why no
_strictvariant. Other intid functions don't havea
_strictform either — the_boundedfamily is the only"reject more inputs" variant. Keeping the surface symmetric
with the rest of the family is the explicit goal of #78.
Test plan
gleam test— 791 passed (was 780; +11 new tests)just check— format-check + lint + check + build + testcompile cleanly with
intid.encode_int_base10(seq)/intid.encode_int_base58(seq)/intid.encode_int_base62(seq)lined up.
Closes #78.