Utility functions used across Sexy: query parsing, number formatting, UUID compression, and struct conversion.
Query format
Sexy uses a compact query format for Telegram callback data:
"/command key1=value1-key2=value2-key3=value3"Values are automatically parsed as integers, floats, or booleans when possible.
Examples
iex> Sexy.Utils.get_query("/buy id=42-amount=9.99-gift=true")
%{id: 42, amount: 9.99, gift: true}
iex> Sexy.Utils.stringify_query(%{id: 42, page: 1})
"id=42-page=1"
iex> Sexy.Utils.fiat_chunk(1234567, 0)
"1 234 567"
Summary
Functions
Format a number with thousands separators (space-separated groups).
Get a value from a map, falling back to default if the key is missing or nil.
Parse a command string and extract query parameters.
Expand a Base62-compressed UUID back to the standard xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
Parse a query string in "key=val-key=val" format into an atom-keyed map.
Convert an atom-keyed map back to a "key=val-key=val" query string.
Compress a UUID string into a short Base62 representation.
Recursively convert string keys to atoms and structs to plain maps.
Functions
@spec fiat_chunk(number(), non_neg_integer()) :: String.t()
Format a number with thousands separators (space-separated groups).
Examples
iex> Sexy.Utils.fiat_chunk(1234567, 0)
"1 234 567"
iex> Sexy.Utils.fiat_chunk(1234.5, 2)
"1 234.50"
Get a value from a map, falling back to default if the key is missing or nil.
Unlike Map.get/3, this also replaces explicit nil values with the default.
Parse a command string and extract query parameters.
Returns an empty map if no parameters are present.
Examples
iex> Sexy.Utils.get_query("/buy id=42-page=1")
%{id: 42, page: 1}
iex> Sexy.Utils.get_query("/start")
%{}
Expand a Base62-compressed UUID back to the standard xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
Example
iex> Sexy.Utils.normalize_uuid("2aUyqjCzEIiEcYMKj7TZtw")
"550e8400-e29b-41d4-a716-446655440000"
Parse a query string in "key=val-key=val" format into an atom-keyed map.
Values may contain - (negative numbers, UUIDs, dates): a - splits pairs
only when followed by a key= sequence. The character sequence -<key>=
inside a value is reserved as the pair separator; = in values is not supported.
Examples
iex> Sexy.Utils.split_query("id=42-name=hello")
%{id: 42, name: "hello"}
iex> Sexy.Utils.split_query("id=-1001234-page=2")
%{id: -1001234, page: 2}
iex> Sexy.Utils.split_query(nil)
%{}
Convert an atom-keyed map back to a "key=val-key=val" query string.
Example
iex> Sexy.Utils.stringify_query(%{id: 42, page: 1})
"id=42-page=1"
Compress a UUID string into a short Base62 representation.
Example
iex> Sexy.Utils.stringify_uuid("550e8400-e29b-41d4-a716-446655440000")
"2aUyqjCzEIiEcYMKj7TZtw"
Recursively convert string keys to atoms and structs to plain maps.
Used internally to normalize Telegram API responses and TDLib JSON before processing.