Skip to content

Support brick/money 0.14 - #24

Draft
robertvansteen wants to merge 2 commits into
mainfrom
brick-money
Draft

Support brick/money 0.14#24
robertvansteen wants to merge 2 commits into
mainfrom
brick-money

Conversation

@robertvansteen

Copy link
Copy Markdown
Contributor

Draft — blocked. Needs gosuperscript/axiom 0.6.9, gosuperscript/interval 2.0.0 and superscript/monetary-interval 0.2.0 tagged first (gosuperscript/axiom#82, gosuperscript/interval#6, gosuperscript/monetary-interval#3). Marking ready once they publish.

brick removed three APIs this package relied on and tightened a fourth:

  • Currency::is() is gone in favour of isEqualTo() (6 call sites).
  • AbstractMoney::to() is now toContext().
  • Money::isAmountAndCurrencyEqualTo() is now isSameValueAs(), which is what =, ==, === and their negations evaluate with.
  • RoundingMode cases are PascalCase, so HALF_UP reads HalfUp.

The tightening that matters is floats. brick now rejects a float anywhere an exact amount is required, because a binary float has no exact decimal value — the literal 0.1 is not one tenth. The host language still hands us int|float scalars, so MoneyParser::exact renders one in the form brick accepts:

public static function exact(string|float|int $amount): string|int
{
    return is_float($amount) ? (string) $amount : $amount;
}

A float becomes the shortest decimal that round-trips to it — the number the source text denoted — while ints and numeric strings are already exact. Every boundary that reads a raw amount goes through it: scalar multiplication and division in MoneyExtension, the coercions in MonetaryType and MinorMonetaryType, and the locale-parsed amount in MoneyParser itself, so the rule lives in one place.

format() took mixed and called Money methods on it unguarded. It now narrows through instance_of first, as the surrounding code does.

Verified against the local chain: PHPStan clean, 136 tests, 100% coverage, MSI 100%.

robertvansteen and others added 2 commits August 5, 2026 18:30
brick removed three APIs this package relied on and tightened a fourth:

- Currency::is() is gone in favour of isEqualTo() (6 call sites).
- AbstractMoney::to() is now toContext().
- Money::isAmountAndCurrencyEqualTo() is now isSameValueAs(), which is what the
  =, ==, === and their negations evaluate with.
- RoundingMode cases are PascalCase, so HALF_UP reads HalfUp.

The tightening that matters is floats. brick now rejects a float anywhere an
exact amount is required, because a binary float has no exact decimal value —
the literal 0.1 is not one tenth. The host language still hands us int|float
scalars, so MoneyParser::exact renders one in the form brick accepts: a float
becomes the shortest decimal that round-trips to it, which is the number the
source text denoted; ints and numeric strings are already exact. Every boundary
that reads a raw amount goes through it — scalar multiplication and division in
MoneyExtension, the coercions in MonetaryType and MinorMonetaryType, and the
locale-parsed amount in MoneyParser itself — so the rule lives in one place.

format() took mixed and called Money methods on it unguarded. It now narrows
through instance_of first, as the surrounding code does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The float conversion vouched for a guarantee it did not provide. PHP's
`(string)` cast on a float honours `precision` — 14 significant digits by
default — not `serialize_precision`, so it truncates and can emit exponent
notation: `(string) 123456789012345.67` is `1.2345678901235E+14`, an amount the
caller never held. `json_encode` honours `serialize_precision` (-1) and yields
the shortest decimal that round-trips, which is what the docblock describes.

Two provider cases pin it — one past 14 significant digits, one that is all
float residue — and both fail on the old cast. A non-finite float names no
decimal at all, so it is refused rather than silently encoded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant