Money.Input.Cast (Money.Input v0.1.0)

View Source

Casts a form-submission shape into a Money.t/0.

cast/2 consumes the four shapes a user-input pipeline can produce:

  • nil and blank-amount maps return {:ok, nil} — the field wasn't filled in.

  • Money.t/0 round-trips unchanged.

  • %{"amount", "currency"} (or %{amount, currency}) — the nested form-submission shape that <.money_input> produces and that Money.Ecto.Composite.Type accepts. The amount field is built with Money.new/3; pass :locale if you need to parse a locale-formatted amount string.

  • A bare binary ("$1,234.56", "1.234,56") delegates to Money.parse/2. Money.parse already handles surrounding whitespace, accounting parens, currency symbols and ISO codes.

The function is modelled after Money.Ecto.Composite.Type.cast/2 (in money_sql) so behaviour stays consistent across the two paths. We host our own copy to avoid taking on ecto_sql as a hard dependency.

Summary

Types

Inputs accepted by cast/2. See the module docs.

Functions

Casts a form-submission value to a Money.t/0.

Types

input()

@type input() ::
  nil | Money.t() | String.t() | %{required(String.t() | atom()) => term()}

Inputs accepted by cast/2. See the module docs.

Functions

cast(input, options \\ [])

@spec cast(input(), Keyword.t()) :: {:ok, Money.t() | nil} | {:error, term()}

Casts a form-submission value to a Money.t/0.

Arguments

Options

  • :locale — locale to use when parsing a locale-formatted amount string. Defaults to Localize.get_locale/0.

  • :currency — fallback currency atom used only when the submitted map omits the currency key. Has no effect when the map provides one.

Returns

  • {:ok, Money.t()} on success.

  • {:ok, nil} for blank input — nil, "", a map with an empty amount, or a map with no amount key at all.

  • {:error, term()} if the cast fails — typically an {exception, message} tuple.

Examples

iex> Money.Input.Cast.cast(%{"amount" => "1234.56", "currency" => "USD"})
{:ok, Money.new(:USD, "1234.56")}

iex> Money.Input.Cast.cast(%{"amount" => "1.234,56", "currency" => "EUR"}, locale: :de)
{:ok, Money.new(:EUR, "1234.56")}

iex> Money.Input.Cast.cast(%{"amount" => "10"}, currency: :JPY)
{:ok, Money.new(:JPY, "10")}

iex> Money.Input.Cast.cast(%{"amount" => "", "currency" => "USD"})
{:ok, nil}

iex> Money.Input.Cast.cast(nil)
{:ok, nil}

iex> Money.Input.Cast.cast(Money.new(:GBP, "5.00"))
{:ok, Money.new(:GBP, "5.00")}