Module: ZeroClick::Sellers::Stateful::Money
- Defined in:
- lib/zeroclick/sellers/stateful/money.rb
Overview
Micro-USD codec for the stateful wire's money strings.
Constant Summary collapse
- MICROS_PER_USD =
1_000_000- MAX_SAFE_MICROS =
Every SDK enforces the same ceiling — 2^53 - 1 — regardless of native integer width, so a value one SDK accepts can never overflow another. Ruby's Integer is arbitrary precision, so this is a contract rule here rather than a language limit: without it Ruby would happily accept amounts the TypeScript SDK cannot represent.
9_007_199_254_740_991- MONEY_RE =
Exactly six fraction digits, no sign, no exponent. The wire format is a fixed-point decimal string precisely so no SDK has to agree with another about float rounding.
/\A\d+\.\d{6}\z/
Class Method Summary collapse
- .format_money_usd(micros) ⇒ Object
- .money_usd?(value) ⇒ Boolean
-
.parse_money_usd(value) ⇒ Object
Returns micro-USD, or nil when the value is not a well-formed money string or exceeds the shared ceiling.
Class Method Details
.format_money_usd(micros) ⇒ Object
41 42 43 44 45 46 47 48 |
# File 'lib/zeroclick/sellers/stateful/money.rb', line 41 def format_money_usd(micros) unless micros.is_a?(Integer) && !micros.is_a?(TrueClass) && micros >= 0 && micros <= MAX_SAFE_MICROS raise Error.new("malformed_input", operation: "format_money_usd", message: "micro-USD must be a non-negative integer within 2^53 - 1") end format("%d.%06d", micros / MICROS_PER_USD, micros % MICROS_PER_USD) end |
.money_usd?(value) ⇒ Boolean
26 27 28 |
# File 'lib/zeroclick/sellers/stateful/money.rb', line 26 def money_usd?(value) value.is_a?(String) && MONEY_RE.match?(value) end |
.parse_money_usd(value) ⇒ Object
Returns micro-USD, or nil when the value is not a well-formed money string or exceeds the shared ceiling. nil rather than an exception: a malformed amount arrives from the wire, so it is an expected input.
33 34 35 36 37 38 39 |
# File 'lib/zeroclick/sellers/stateful/money.rb', line 33 def parse_money_usd(value) return nil unless money_usd?(value) whole, fraction = value.split(".") micros = (whole.to_i * MICROS_PER_USD) + fraction.to_i micros <= MAX_SAFE_MICROS ? micros : nil end |