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.

pub const int64_max: Int

Largest value that fits in a signed 64-bit integer (2^63 - 1). Use as the max argument to decode_int_*_bounded when the decoded value flows into a column declared BIGINT (Postgres, MySQL) or INTEGER (SQLite).

Search Document