Pure, locale-free, deterministic formatting helpers for money, dates, and labels.
These helpers back the built-in recipes (Rendro.Recipes.Invoice,
Rendro.Recipes.Statement, Rendro.Recipes.Receipt, and friends) and are safe
to call directly when you want the same deterministic formatting outside a
recipe. Rendro.Format performs no CLDR/gettext/locale lookups — output is
byte-identical across runs and machines; internationalization stays a
caller-supplied :formatters/:labels override, never core.
Migration note
Rendro.Format was previously an internal module (@moduledoc false). It is
now public at the adapter/Evolving tier: money/1, date/1, and label/1
are the supported surface, with unchanged behavior from their prior internal
use.
Stability caveat
Formatted output may evolve across minor versions (e.g. grouping, rounding, or label wording could be refined). Callers who need an exact, frozen string should pin it in their own golden/snapshot tests rather than relying on the literal output staying fixed forever.
Summary
Functions
Formats a Date as an ISO 8601 YYYY-MM-DD string.
Locale-independent (uses Date.to_iso8601/1) and byte-identical across runs.
Examples
iex> Rendro.Format.date(~D[2026-05-29])
"2026-05-29"
@spec label( :balance | :brought_forward | :carried_forward | :opening_balance | :closing_balance ) :: String.t()
Returns the default English label for a statement field.
Supported keys: :balance, :brought_forward, :carried_forward,
:opening_balance, :closing_balance.
Examples
iex> Rendro.Format.label(:carried_forward)
"Carried forward"
iex> Rendro.Format.label(:opening_balance)
"Opening balance"
Formats a Decimal money amount as a deterministic grouped currency string.
The amount is rounded to 2 decimal places (half-up), the integer part is grouped
into comma-separated thousands, prefixed with $, and negatives are wrapped in
parentheses with no leading minus. The result is locale-independent and
byte-identical across runs.
Examples
iex> Rendro.Format.money(Decimal.new("1234.5"))
"$1,234.50"
iex> Rendro.Format.money(Decimal.new("1234.567"))
"$1,234.57"
iex> Rendro.Format.money(Decimal.new("-1234.5"))
"($1,234.50)"
iex> Rendro.Format.money(Decimal.new("0"))
"$0.00"
iex> Rendro.Format.money(Decimal.new("1000000"))
"$1,000,000.00"