Accrue.Money (accrue v0.3.0)

Copy Markdown View Source

Accrue's canonical money value type — a thin, opinionated wrapper over the :ex_money currency table.

Shape

%Accrue.Money{amount_minor: integer(), currency: atom()} — amounts are always stored in the currency's minor unit (cents for USD, yen for JPY, fils-thousandths for KWD). The currency is always an atom matching the lowercase ISO 4217 code (:usd, :jpy, :kwd).

Constructor discipline (D-03)

The primary constructor is new/2 with an integer in minor units — the same shape Stripe's API uses, so developers can paste Stripe integers directly:

iex> Accrue.Money.new(1000, :usd)
%Accrue.Money{amount_minor: 1000, currency: :usd}   # $10.00

Passing a Decimal or a float to new/2 raises ArgumentError. Use from_decimal/2 for explicit decimal conversions — the shift to minor units is currency-exponent aware via ex_money's CLDR table.

Cross-currency arithmetic (D-04)

Operations on two Accrue.Money values with different currencies raise Accrue.Money.MismatchedCurrencyError. There are no silent FX conversions and no tagged-tuple returns — the failure is loud and immediate at the call site.

Summary

Functions

Addition. Raises Accrue.Money.MismatchedCurrencyError on currency mismatch (D-04).

Structural equality — same amount_minor AND same currency atom.

Decimal constructor — shifts the value into the currency's minor unit according to ex_money's CLDR iso_digits for that currency.

Primary integer-minor-unit constructor.

Subtraction. Raises Accrue.Money.MismatchedCurrencyError on currency mismatch (D-04).

Human-readable formatting. Delegates to ex_money's CLDR-backed formatter, which handles locale-aware currency symbols and grouping.

Types

t()

@type t() :: %Accrue.Money{amount_minor: integer(), currency: atom()}

Functions

add(a, b)

@spec add(t(), t()) :: t()

Addition. Raises Accrue.Money.MismatchedCurrencyError on currency mismatch (D-04).

equal?(a, b)

@spec equal?(t(), t()) :: boolean()

Structural equality — same amount_minor AND same currency atom.

from_decimal(decimal, currency)

@spec from_decimal(Decimal.t(), atom()) :: t()

Decimal constructor — shifts the value into the currency's minor unit according to ex_money's CLDR iso_digits for that currency.

Zero-decimal currencies (JPY, KRW) do not shift. Three-decimal currencies (KWD, BHD) multiply by 1000. Rounding is half-even (banker's rounding), matching Stripe's default.

new(amount_minor, currency)

@spec new(integer(), atom()) :: t()

Primary integer-minor-unit constructor.

Raises ArgumentError when given a float or a Decimal. Use from_decimal/2 for decimal conversions.

Raises ArgumentError if the currency atom is not a known ISO 4217 code.

subtract(a, b)

@spec subtract(t(), t()) :: t()

Subtraction. Raises Accrue.Money.MismatchedCurrencyError on currency mismatch (D-04).

to_string(money)

@spec to_string(t()) :: String.t()

Human-readable formatting. Delegates to ex_money's CLDR-backed formatter, which handles locale-aware currency symbols and grouping.