yabase/intid
Integer helpers for short URL-safe identifiers.
The byte-oriented codecs in yabase/facade are the right tool when
the input is opaque bytes (hashes, public keys, raw payloads). For
the very common short-ID case — DB autoincrement ids, sequence
numbers, hash truncations — callers want Int -> compact string
directly. Without these helpers every project re-implements the
same Int -> big-endian bytes -> trim-leading-zero shim.
encode_int_* emits canonical form: no leading zero characters
beyond what the value itself requires (encode_int_base58(0) == "1", the alphabet’s zero character; encode_int_base58(58) == "21", no leading "1").
decode_int_* is tolerant of leading zero characters
(decode_int_base58("0042") and decode_int_base58("42") both
return the same Int), so input from external sources that
zero-pads is accepted without ceremony.
decode_int_* rejects the empty string with
Error(InvalidLength(0)) rather than treating it as zero. Callers
can therefore distinguish “no ID was supplied” from “the ID is
zero” — important for URL routing, form parsing, and database
lookups. The byte-oriented decoders in yabase/facade retain the
Ok(<<>>) round-trip behavior for empty input.
Negative inputs are normalized to int.absolute_value before
encoding — the magnitude is what gets stored. The decode side
always returns a non-negative Int.
Bounded decode
decode_int_* accepts inputs of any length, so the decoded
Int can exceed any fixed integer width — Erlang Int is a
bignum. Realistic backing stores cap IDs at 64 bits (SQLite
INTEGER, Postgres bigserial, MySQL BIGINT), so feeding an
unbounded decode_int_* result into one of those columns
crashes the driver as soon as a user supplies a slightly-too-long
string. For the same reason, JavaScript-target callers cap at
53 bits (Number.MAX_SAFE_INTEGER).
Use decode_int_*_bounded(input:, max:) whenever the decoded value
flows into a fixed-width sink. The bounded variants return
Error(Overflow) if the decoded Int exceeds max. Common caps
are exported as int64_max (signed 64-bit, 2^63 - 1) and
int53_max (JS-safe integer, 2^53 - 1).
Types
Issue #74: every decode_int_* function in this module returns
Result(Int, CodecError). Without this re-export, callers who only
import yabase/intid cannot type-annotate a wrapper around a
decode call without reaching into yabase/core/error — a module
the README does not mention. The alias keeps the type identity
(it’s the same CodecError the underlying codec functions
already use) so error values flow through unchanged.
pub type CodecError =
error.CodecError
Values
pub fn decode_int_base32_crockford(
input: String,
) -> Result(Int, error.CodecError)
Decode a Crockford Base32 string back to an Int.
pub fn decode_int_base32_crockford_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Crockford Base32 string back to an Int, rejecting
values greater than max with Error(Overflow).
pub fn decode_int_base32_crockford_check(
input: String,
) -> Result(Int, error.CodecError)
Decode a checksummed Crockford Base32 string back to an Int,
verifying the trailing check symbol.
pub fn decode_int_base32_crockford_check_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a checksummed Crockford Base32 string back to an Int,
rejecting values greater than max with Error(Overflow).
pub fn decode_int_base32_rfc4648(
input: String,
) -> Result(Int, error.CodecError)
Decode a Base32 (RFC 4648) string back to an Int.
pub fn decode_int_base32_rfc4648_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Base32 (RFC 4648) string back to an Int, rejecting
values greater than max with Error(Overflow).
pub fn decode_int_base36(
input: String,
) -> Result(Int, error.CodecError)
Decode a Base36 string back to an Int.
pub fn decode_int_base36_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Base36 string back to an Int, rejecting values
greater than max with Error(Overflow).
pub fn decode_int_base58(
input: String,
) -> Result(Int, error.CodecError)
Decode a Base58 (Bitcoin alphabet) string back to an Int.
pub fn decode_int_base58_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Base58 (Bitcoin alphabet) string back to an Int,
rejecting values greater than max with Error(Overflow).
pub fn decode_int_base58_flickr(
input: String,
) -> Result(Int, error.CodecError)
Decode a Base58 (Flickr alphabet) string back to an Int.
pub fn decode_int_base58_flickr_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Base58 (Flickr alphabet) string back to an Int,
rejecting values greater than max with Error(Overflow).
pub fn decode_int_base58check(
input: String,
) -> Result(Int, error.CodecError)
Decode a Base58Check string back to an Int, verifying the
4-byte SHA-256 checksum.
Issue #73: returns the payload as an Int, ignoring the version
byte (which encode_int_base58check always sets to 0).
Callers that need to inspect the version byte should reach for
yabase/base58check.decode/1 directly.
pub fn decode_int_base58check_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Base58Check string back to an Int, rejecting payload
values greater than max with Error(Overflow). The checksum is
verified before the bounds check, so a corrupted input fails as
InvalidChecksum rather than Overflow.
pub fn decode_int_base62(
input: String,
) -> Result(Int, error.CodecError)
Decode a Base62 string back to an Int.
pub fn decode_int_base62_bounded(
input input: String,
max max: Int,
) -> Result(Int, error.CodecError)
Decode a Base62 string back to an Int, rejecting values
greater than max with Error(Overflow).
pub fn encode_int_base32_crockford(value: Int) -> String
Encode a non-negative Int as a Crockford Base32 string.
pub fn encode_int_base32_crockford_check(value: Int) -> String
Encode a non-negative Int as a Crockford Base32 string with a
trailing checksum symbol (Douglas Crockford’s optional check
character).
Issue #73: same shape as encode_int_base32_crockford but with
the typo-resistance guard the underlying codec already supports.
Use the matching decode_int_base32_crockford_check to recover
the integer; the decoder verifies the symbol and returns
Error(InvalidChecksum) if the input was mistyped.
pub fn encode_int_base32_rfc4648(value: Int) -> String
Encode a non-negative Int as a Base32 (RFC 4648) string.
pub fn encode_int_base36(value: Int) -> String
Encode a non-negative Int as a Base36 string.
pub fn encode_int_base58(value: Int) -> String
Encode a non-negative Int as a Base58 (Bitcoin alphabet) string.
pub fn encode_int_base58_flickr(value: Int) -> String
Encode a non-negative Int as a Base58 (Flickr alphabet) string.
pub fn encode_int_base58check(value: Int) -> String
Encode a non-negative Int as a Base58Check string (Bitcoin’s
double-SHA-256 checksum format).
Issue #73: this is the int-typed counterpart of
yabase/base58check.encode/2. Version is fixed at 0
(Bitcoin mainnet P2PKH) — callers that need a different version
should reach for yabase/base58check.encode/2 directly with their
own BitArray payload.
Returns the canonical Base58Check string. The underlying
yabase/base58check.encode only errors on out-of-range version
bytes (this helper hard-codes a valid one), so this signature
does not surface a Result.
pub fn encode_int_base62(value: Int) -> String
Encode a non-negative Int as a Base62 string.
pub const int53_max: Int
Largest value that round-trips losslessly through a JavaScript
number (2^53 - 1, Number.MAX_SAFE_INTEGER). Use as the
max argument to decode_int_*_bounded when the decoded value
is passed across a JS-target boundary or serialized as JSON for
a JavaScript consumer.